UP | HOME

clojure

Table of Contents

graph databases: https://www.youtube.com/watch?v=tbVwmFBnfo4

datascript domain model: https://vvvvalvalval.github.io/posts/2018-07-23-datascript-as-a-lingua-franca-for-domain-modeling.html

macchiato server https://dev.solita.fi/2020/05/26/clojurescript-web-serverwith-macchiato-shadowcljs-and-reitit.html

articles to read: https://www.infoq.com/articles/clojure-donkey-http-stack/ http stack https://purelyfunctional.tv/article/react-vs-re-frame/ react vs reframe https://purelyfunctional.tv/guide/clojure-concurrency/

transducers explanation: https://eli.thegreenplace.net/2017/reducers-transducers-and-coreasync-in-clojure/

you call the library the framework calls you

clojure speed https://tech.redplanetlabs.com/2020/09/02/clojure-faster/

routing https://github.com/metosin/reitit

left off the tutorial here: https://www.braveclojure.com/concurrency/

also deffinitely need more to look into macros

M-x cider-jack-in connect to leiningen

M-x cider-jack-in-cljs to connect to a cljs repl!

quit repl (System/exit 0)

quit js repl :cljs/quit

clj kondo

yay -S clj-kondo-bin
add (!package flycheck-clj-kondo)
enable the checker

0.1 questions

  1. how to make the following less verbose?
(s/fdef named-note
  :args (s/cat :step ::step
               :range ::range
               :name ::name
               :flat-of-name ::flat-of-name
               :sharp-of-name ::sharp-of-name))
(defn named-note
  ([step range name] {:step step
                      :range range
                      :name name})
  ([step range name flat-of-name sharp-of-name] {:step step
                                           :range range
                                           :name name
                                           :flat-of-name flat-of-name
                                           :sharp-of-name sharp-of-name}))

0.2 spec

1 emacs key commandx

emacs kbd doom cmd what do comand
C-x C-e   send line to repl  
C-c M-n M-n   set repl namespace to current file cider-repl-set-ns
C-c C-k   recomplile current file in repl  
C-up or C-down   last commands  
C-c C-d C-d   explain symbol under pointer  
M-. spc c d go to code  
M-,   return from code  
C-c C-d C-a   search function names  
       
  1. TODO paredit ersearch   personal

    https://github.com/georgek/paredit-cheatsheet/blob/master/paredit-cheatsheet.pdf

    paredit forward slurp needs key command, maybe C-> paredit-forward-slurp-sexp paredit-forward-barf-sexp

1.1 basics

nil, true, false, if, do, =when, nil?,

(nil? 1) ;; false

falsy: nil, false truthy: everything else

(or false 4) ; 4 (or 4 false) ; 4 (and 4 5) ; 5

bind instead of assign

  1. hashmap {}

    (get MAP key default) (get-in MAP [:key :path] default)

    (MAP :key) (MAP :key default) (:key MAP default)

    into

    => (def m {:a "jeu"})
    => (into m {:b "kk"})
    {:a "jeu", :b "kk"}
    

    also see assoc

    (assoc {:a 1} :b 2)
    ;f{:a 1 :b 2}
    
    
  2. vectors []

    conj adds one to the vector end (get VECTOR index)

    => (def z [m])
    => (into z #{{:b "kk"}})
    [{:a "jeu"} {:b "kk"}]
    
  3. lists '()

    no get, nth instead conj adds to lost beginning

  4. hashed sets #{}

    hash-set creates conj (set VECTOR) (contains? #{} :key) get

  5. functions
    (defn function-name
           "doc string"
           [args]
           (res))
    
    ; multi arity
    (defn funk
      ([arg1 arg3] (something))
      ([arg1] (something)))
    
    (defn funk
      [arg & rest]
      (something))
    

    anonymous (fn [args] (body)) #(* % 3) arg gets inserted in % further %1 %2 %&

    1. let

      (let [x 0] x) ;0

  6. loop

    it’s almost exactly like a function, that allows tail calling

    (loop [arg 0] (recur (inc arg))) ; infinite loop.  =recur= calls the func
    
    1. Destructuring
      (defn my-first-fink
        [[first-thing second-thing]]
        [first-thing second-thing])
      

      same for maps: [{lat :lat lng :lng}] var name to keyword or: {:keys [lat lng]} keep OG {:keys [lat lng] :as treasure-location}

  7. Sequence functions

    filter, take, drop, take-while, drop-while, some, sort, sortBy, concat repeat, repeatedly lazy

    1. reduce, map
      (reduce + 15 [1 2 3 4])
      (reduce + [1 2 3 4])
      (map str ["a" "b" "c" "d"] ["A" "B" "C"])
      ; => ("aA" "bB" "cC")
      
  8. Collection functions

    empty, every

  9. Function functions

    partial, apply, complement comp, memoize

  10. comp vs -> (pipe)
    (def m {:a {:b {:c "hi!"}}})
    (-> m :a :b :c)
    ; "hi!"
    ((comp :a :b :c) m)
    ; nil
    ((comp :c :b :a) m)
    ; "hi!"
    
    
  11. regular expressions

    re-find seems pretty useful

    (re-find #"^left-" "left-eye")
    ; => "left-"
    (re-find #"^left-" "cleft-chin")
    ; => nil
    (re-find #"^left-" "wongleblart")
    ; => nil
    
  12. time

    (time (vampire-related-details 0)) (Thread/sleep 1000)

  13. cons

    cons(truct) a seq conj(oin) an item

    => (def m (seq {:a 1 :b 2 :c 3}))
    ([:a 1] [:b 2] [:c 3])
    => (into {} m)
    {:a 1, :b 2, :c 3}
    
  14. require

    (require ’[the-divine-cheese-code.visualization.svg :as svg])

    cheaply (use ’[the-divine-cheese-code.visualization.svg :as svg])

2 previous

## learning clojure

I will only concentrate on clojurescript for now because everything JVM might be beyond me.

lumo is SELF HOSTED - which means it can’t contain any JVM components. realistically it means you cant use `core.async` - there is an alrernative lib called `andare` which can be used. for the most part when using `lumo` you will install dependencies through npm

### errors

when using andare with lumo, with the following lumo file

``` (require ’[lumo.build.api :as b])

(b/watch “src” {:main ’read.core :output-to “watch/main.js” :output-dir “watch” :optimizations :advanced :verbose true :foreign-libs [{:file “src” :module-type :es6}] :watch-fn (fn [] (println “Updated build”)) :target :nodejs}) ```

it would work once, but on second compile without deleting `watch/` the following error would happen ``` #error {:message failed compiling src/read/core.cljs, :data {:file src/read/core.cljs}, :cause #error {:message Could not require cljs.core.async, :data {:tag :cljs/analysis-error}, :cause #object[Error Error: No eval-fn set]}} ```

I haven’t actually been able to fix this yet. The watch just doesn’t work - I have to delete the watch folder every single time i want to regenerate the resources.

this tutorial [seems very good about showing how core.async actually works](https://www.bradcypert.com/clojure-async/)

Author: John Doe

Created: 2021-04-25 Sun 15:56