AmitKumarDas / Decisions

Apache License 2.0
10 stars 3 forks source link

diary 2020 #271

Open AmitKumarDas opened 3 years ago

AmitKumarDas commented 3 years ago

Learn & Teach -- Sticky

Racket -- Sticky

AmitKumarDas commented 3 years ago

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 commented 3 years ago

Day 0 with Racket

Observations

Keywords so far

Special chars -- the Racketeer way

In the WILD

AmitKumarDas commented 3 years ago

MLOps

Learnings

AmitKumarDas commented 3 years ago

Datalog - The only query language you ever need

refer

AmitKumarDas commented 3 years ago

GraphQL

Select Keys


(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 commented 3 years ago

Plan to Clojure & Racket

AmitKumarDas commented 3 years ago

What's this in Clojure?

Clojure land tips

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

Datalog for querying

(friend ?a ?a)
(or [[?a friend ?b]]
    [[?a friend ?x]
     (friend ?x ?b)])
AmitKumarDas commented 3 years ago

TODO

Clojure specs

Clojure vs Java

AmitKumarDas commented 3 years ago

Web Frameworks in clj

AmitKumarDas commented 3 years ago

;; bad (. "hello" substring 1 3)

```clj
;;; instance field access
;; good
(.someField some-object)

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

;; bad
(. Integer MAX_VALUE)

;; bad (cons 1 (cons 2 (cons 3 [4 5])))


- naming
```clj
;; good
(def some-var ...)
(defn some-fun ...)
;; bad
(def someVar ...)
(defn somefun ...)
(def some_fun ...)
(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

AmitKumarDas commented 3 years ago
;; 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 commented 3 years ago
;; 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 commented 3 years ago

TODO

clojure folks

clojurescript

go

James Tanton Books

AmitKumarDas commented 3 years ago

Systems Design