Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

diary 2020 #271

Open
AmitKumarDas opened this issue Aug 17, 2020 · 20 comments
Open

diary 2020 #271

AmitKumarDas opened this issue Aug 17, 2020 · 20 comments

Comments

@AmitKumarDas
Copy link
Owner Author

Setup up a Google Kubernetes Engine (GKE) cluster in the Google Cloud

gcloud auth login
gcloud config set project your-project-name
gcloud container clusters create \
  --zone us-central1-a your-cluster-name \
  --cluster-version 1.15 \
  --num-nodes=3

After you have a running GKE cluster (or are prepared to use an existing one) you need to create a Cluster Role Binding for Kubernetes to authorize your Google Cloud username as a valid Kubernetes cluster-admin.

kubectl create clusterrolebinding cluster-admin-binding-$USER \
  --clusterrole=cluster-admin \
  --user=$(gcloud config get-value core/account)

To switch to a namespace run the following:

kubectl config set-context --current --namespace=my-namespace

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Aug 17, 2020

Day 0 with Racket

  • my installed path
bin > pwd
/home/amit/rustdev/.../bin

Observations

  • Names are delimited by hypen i.e. -
  • Names are small cased completely
  • You can write code in a way that is soothing to your eyes instead of bothering about parentheses
  • ; semi-colon starts a line comment
  • , comma(s) are not found
  • I was little confused with the way [ ] parens are used
  • Each [ ] seems to denote an item & again no presence of , comma(s) yet
  • let is used for local binding
  • let* is same as let but can refer to just defined bindings
    • perfect to achieve more with little lines of code

Keywords so far

  • let
  • let*
  • define

Special chars -- the Racketeer way

  • - hyphen
  • () simple parens
  • [] rectangle parens
  • space is used as the canonical delimiter; just like how a human thinks
  • "" to define strings

In the WILD

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Aug 19, 2020

MLOps

Learnings

  • Docker machine to create VMs in any cloud or bare metals

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Aug 27, 2020

Datalog - The only query language you ever need

  • Lisp / Clojure / Racket / etc are is all about Declarative Data Structure
    • Learn this one thing i.e. LISP
    • Do anything you have ever imagined / wanted to do
  • [E A V] is all you need
    • E is entity
    • A is attribute
    • V is value
  • Above can be pattern matched & more
  • Read more on datascript , datomic
  • How do you index E A V in your favourite database
 Structure            Index
 key/value (nosql)    A V E
 row (mysql)          E A V
 column               A E V
 document (mongo)     E A V
 graph (Neo4J)        V A E
 search (Lucene)      inverted-index
  • If update are required then [E A V Tx Op]

refer

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Aug 28, 2020

GraphQL

  • Thought for the day
    • Can we use GraphQL i.e. query language as a DSL to test features composed of REST APIs?
    • Its not just testing that needs above DSL. Its the frontend layer that needs this as well
    • Here is the reference: https://youtu.be/UvJEBMOtayk
  • But then hey GraphQL is NOT perfect

Select Keys

  • These are the things WE are interested in
  • Signature select-keys-from {} []
    • select keys from a structure
(select-keys-from 
  {:id "121awsaw"
   :name "amitd"}
  [:title])

;; =>
;; {:title "amitd"}

QUOTE: Clojure data structures looks like a rare breed of yaml and json that exhibits the best of both worlds & eliminates all their bad parts. Don't get fixated with its indentation or braces else you fail to grasp its real magic.

QUOTE: Can we use Clojure to get a better jsonpath or jq that helps us to find, traverse and extract attributes of a data structure?

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Aug 31, 2020

Plan to Clojure & Racket

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 1, 2020

What's this in Clojure?

Clojure land tips

  • You do not say arguments but argument vector
  • Prefer higher-order functions like map to loop/recur

Get your indentations right

(ns examples.ns
  (:refer-clojure :exclude [next replace remove])
  (:require [clojure.string :as s :refer [blank?]])
  (:import java.util.Date))
;; better
(ns examples.ns
  (:require
   [clojure.string :as s :refer [blank?]]
   [clojure.set :as set]
   [clojure.java.shell :as sh])
  (:import
   java.util.Date
   java.text.SimpleDateFormat
   [java.util.concurrent Executors
                         LinkedBlockingQueue]))

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 3, 2020

On writing clojure functions

;; good when argument vector & logic are separated
;; into multiple lines
(defn foo [x]
  (bar x))

;; single line implementation is good for a small function body
(defn foo [x] (bar x))

;; good for multi-arity functions
;; what is predicate?
(defn foo
  ([x] (bar x))
  ([x y]
   (if (predicate? x)
     (bar x)
     (baz x))))

;; good - it's easy to scan for the nth arity
(defn foo
  "I have two arities."
  ([x]
   (foo x 1))
  ([x y]
   (+ x y)))

;; okay - the other arities are applications of the two-arity
(defn foo
  "I have two arities."
  ([x y]
   (+ x y))
  ([x]
   (foo x 1))
  ([x y z & more]
   (reduce foo (foo x (foo y z)) more)))

;; good to prefer pre & post conditions inside function body
(defn foo [x]
  {:pre [(pos? x)]}
  (bar x))

;; bad
(defn foo [x]
  (if (pos? x)
    (bar x)
    (throw (IllegalArgumentException. "x must be a positive number!")))

@AmitKumarDas
Copy link
Owner Author

def in clojure

;; good to group defs together
(def min-rows 10)
(def max-rows 20)
(def min-cols 15)
(def max-cols 30)

;; very bad to define variables inside function
(defn foo []
  (def x 5)
  ...)
;; do not shadow clojure.core names with local bindings
;; bad - clojure.core/map must be fully qualified inside the function
(defn foo [map]
  ...)
;; use alter-var-root instead of def to change the value of a var
;; good
(def thing 1) ; value of thing is now 1
; do some stuff with thing
(alter-var-root #'thing (constantly nil)) ; value of thing is now nil

;; bad
(def thing 1)
; do some stuff with thing
(def thing nil)
; value of thing is now nil
;; Use seq as a terminating condition to test whether a sequence is empty 
;; (this technique is sometimes called nil punning)
;; good
(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

;; bad
(defn print-seq [s]
  (when-not (empty? s)
    (prn (first s))
    (recur (rest s))))

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 3, 2020

Others in clojure

;; good
(printf "Hello, %s!\n" name)

;; ok
(println (format "Hello, %s!" name))
;; good
(< 5 x 10)

;; bad
(and (> x 5) (< x 10))
;; prefer % over %1 in function literals with only one parameter.

;; good
#(Math/round %)

;; bad
#(Math/round %1)
;; prefer %1 over % in function literals with more than one parameter.

;; good
#(Math/pow %1 %2)

;; bad
#(Math/pow % %2)
;; don’t wrap functions in anonymous functions when you don’t need to.

;; good
(filter even? (range 1 10))

;; bad
(filter #(even? %) (range 1 10))
;; Don’t use function literals if the function body will consist 
;; of more than one form
;; Is function literals same as anonymous functions?

;; good
(fn [x]
  (println x)
  (* x 2))

;; bad (you need an explicit do form)
#(do (println %)
     (* % 2))

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 3, 2020

More in clojure

;; favor the use of complement versus the use of an anonymous function
;; this rule should be ignored if the complementing predicate exists in the
;; form of a separate function (e.g. even? and odd?).

;; good
(filter (complement some-pred?) coll)

;; bad
(filter #(not (some-pred? %)) coll)
;; favor comp over anonymous functions for function composition

;; Assuming `(:require [clojure.string :as str])`...

;; good
(map #(str/capitalize (str/trim %)) ["top " " test "])

;; better
(map (comp str/capitalize str/trim) ["top " " test "])
;; favor partial over anonymous functions for currying

;; good
(map #(+ 5 %) (range 1 10))

;; (arguably) better
(map (partial + 5) (range 1 10))

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 3, 2020

Moar in clojure

;; cond is like switch case in clojure

;; good
(cond
  (neg? n) "negative"
  (pos? n) "positive"
  :else "zero")

;; bad
(cond
  (neg? n) "negative"
  (pos? n) "positive"
  true "zero")
;; good
(cond
  (= x 10) :ten
  (= x 20) :twenty
  (= x 30) :thirty
  :else :dunno)

;; cond with predicate
;; much better
(condp = x
  10 :ten
  20 :twenty
  30 :thirty
  :dunno)

;; best
(case x
  10 :ten
  20 :twenty
  30 :forty
  :dunno)

@AmitKumarDas
Copy link
Owner Author

Datalog for querying

(friend ?a ?a)
(or [[?a friend ?b]]
    [[?a friend ?x]
     (friend ?x ?b)])
  • Entity Attribute Value
  • E A V
1 name amit
1 age 38
1 lives india
1 pet bear
1 per dog
1 friend 2
  • Query via pattern matching ~ datalog
  • individual queries
1 name ?who
?id lives india
  • implicit join
?x name amit
?x lives moscow
?id name amit
?id lives ?city

@AmitKumarDas
Copy link
Owner Author

Web Frameworks in clj

  • refer https://youtu.be/2fLx4fu9VV8
  • React - May 2013
  • Om - Dec 2013 - read David Nolem's famous blogpost
    • centrailised state atom
    • async rendering
    • leveraged immutability
    • a big framework
  • Reagent - Jan 2014
    • Reactive atoms - chain or something
    • Hiccup syntax to define UI
    • a big framework
  • Quiescent - Feb 2014
    • no state model
    • minimal
    • pure functional.. no oop
    • search framework or something
    • easy for clojure / lisp fans
  • Rum - Dec 2014
  • Re-Frame
  • Om.Next

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 7, 2020

  • How to invoke instance methods or fields
  • How to invoke static methods
;;; instance method invocation
;; good
(.substring "hello" 1 3)

;; bad
(. "hello" substring 1 3)
;;; instance field access
;; good
(.someField some-object)

;; bad
(. some-object someField)
;;; static field access
;; good
Integer/MAX_VALUE

;; bad
(. Integer MAX_VALUE)
  • use list* instead of a series of nested cons invocations
;; good
(list* 1 2 3 [4 5])

;; bad
(cons 1 (cons 2 (cons 3 [4 5])))
  • naming
;; good
(def some-var ...)
(defn some-fun ...)
;; bad
(def someVar ...)
(defn somefun ...)
(def some_fun ...)
  • Figwheel is a ClojureScript build tool and REPL

    • Enables an expressive live programming model i.e. interactive application development
    • Plays well with text editors that make traditional REPL integration more challenging
  • Leiningen project.clj file declares a variety of properties about project

  • The most important is the list of :dependencies

(defproject om-tutorial "0.1.0-SNAPSHOT"
  :description "My first Om program!"
  :dependencies [[org.clojure/clojure "1.10.1"]
                 [org.clojure/clojurescript "1.10.520"]
                 [org.omcljs/om "1.0.0-beta4"]
                 [figwheel-sidecar "0.5.19" :scope "test"]])
  • @amitd notes
    • Just a single ()
    • More vectors, nested vectors
    • When to use keywords
    • When to use namespaced symbols
    • When to use non-namespaced symbols
    • Namespace is more like a URI
    • How are the values arranged in a vector
    • Namespace & static both use /
(require '[figwheel-sidecar.repl :as r]
         '[figwheel-sidecar.repl-api :as ra])

(ra/start-figwheel!
  {:figwheel-options {}
   :build-ids ["dev"]
   :all-builds
   [{:id "dev"
     :figwheel true
     :source-paths ["src"]
     :compiler {:main 'om-tutorial.core
                :asset-path "js"
                :output-to "resources/public/js/main.js"
                :output-dir "resources/public/js"
                :verbose true}}]})

(ra/cljs-repl)

@amitd observes

  • ' is used in two places
  • ' is used at require
  • ' is used before clojure namespace

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 7, 2020

;; good
{:name "Bruce" :age 30}

;; bad
{"name" "Bruce" "age" 30}
;; good
[1 2 3]
#{1 2 3}
(hash-set (func1) (func2)) ; values determined at runtime

;; bad
(vector 1 2 3)
(hash-set 1 2 3)
#{(func1) (func2)} ; will throw runtime exception if (func1) = (func2)

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 8, 2020

;; use CamelCase for protocols, records, structs, and types
;; keep acronyms like HTTP, RFC, XML uppercase
;; changing state functions should be named with exclamation mark
;; names of functions/macros that are not safe in STM transactions 
;; should end with an exclamation mark (e.g. reset!).
;; names of predicate methods should end in a question mark
;; note - predicate method return boolean
;; (e.g., even?).

;; good
(defn palindrome? ...)

;; bad
(defn palindrome-p ...) ; Common Lisp style
(defn is-palindrome ...) ; Java style
;; Don’t use the interop syntax to construct type and record instances
;; deftype and defrecord automatically create constructor functions
;; Use those instead of the interop syntax, 
;; as they make it clear that you’re dealing with a deftype or a defrecord

(defrecord Foo [a b])
(deftype Bar [a b])

;; good
(->Foo 1 2)
(map->Foo {:b 4 :a 3})
(->Bar 1 2)

;; bad
(Foo. 1 2)
(Bar. 1 2)

;; deftype doesn’t define the map->Type constructor
;; It’s available only for records
(defrecord Customer [id name phone email])

(defn make-customer
  "Creates a new customer record."
  [{:keys [name phone email]}]
  {:pre [(string? name)
         (valid-phone? phone)
         (valid-email? email)]}
  (->Customer (next-id) name phone email))

@AmitKumarDas
Copy link
Owner Author

AmitKumarDas commented Sep 11, 2020

TODO

clojure folks

  • David Nolen

clojurescript

go

James Tanton Books

  • james tanton books - search in google

@AmitKumarDas
Copy link
Owner Author

Systems Design

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant