Clojure(Script) promo

Created by Kamil Stasiak

Themes

Black (default) - White - League - Sky - Beige - Simple
Serif - Blood - Night - Moon - Solarized

  • Compile to Java Bytecode, JavaScript or CLR (.Net)
  • LISP dialect
  • Java / JavaScript interop
  • Immutable and mostly lazy

Syntax

Strings


                ; ClojureScript
                "Hello world"
                "My name
                is bob" ; multiline string
                

                // Java
                "Hello world"
                

                // JavaScript
                'Hello world'
                "Hello world"
                `Hello world`
                

Keywords


:name
{:name "Bob", :surname "Smith"} ; keys in maps

Symbols


hello-world
if
main
get-name

List


                    ; ClojureScript
                    '(1 2 3)
                    '("1" :two  3 "four")

                        // Java
                        new LinkedList(1, 2, 3)
                        Arrays.asList(1, 2, 3)

                        // Kotlin
                        listOf(1, 2, 3)

Vectors


                    ; ClojureScript
                    [1 2 3]
                    ["1" :two  3 "four"]

                        // Java
                        new ArrayList(1, 2, 3)

                        // JavaScript
                        [1, 2, 3]

Maps


                ; ClojureScript
                { :name "Bob"
                  "age" 12
                  :greet #("Hello world")} ; function


// JavaScript
{ name: "Bob",
  age: 12,
  greet: () => "Hello world"}

Sets


; ClojureScript
#{"Apple" "Orange" "Apple"} ; => #{"Apple" "Orange"}

// Java
Set set = new HashSet<String>();
set.addAll("Apple", "Orange", "Apple")

Data structures overview


                        ; ClojureScript
                        (= '(1 2 3) '(1 2 3)) ; true

// JavaScript
[1 2 3] === [1 2 3] // false

Parenthesis


; ClojureScript
(print "Hello world")

// JavaScript
print('Hello world')
                

; ClojureScript, 10 parenthesis
(defn absolute [num]
 (if (< num 0)
  (- num)
 num))

// JavaScript, 10 parenthesis
function absolute(num) {
 if (num < 0) {
  return -num;
 } else {
  return num;
 }
}
                

; ClojureScript
(+ 2 (* 3 3))

// JavaScript
2 + 3 * 3
                

; ClojureScript
(defn absolute [num]
 (if (< num 0)
  (- num)
 num)) ; 10

// JavaScript
const absolute = (num) => num > 0 ? num : -num // 2
                
Lisp cycles xkcd

CODE


                (defn print-vat [money]
                  (let [amount (:amount money)
                        currency (:currency money)
                        calculated (* amount 1.23)]
                    (print (str calculated " " currency))))

                (print-vat {:amount 100 :currency "PLN"})
                            

IS DATA


                (defn print-vat [{:keys [amount currency]}]
                  (let [calculated (* amount 1.23)]
                    (print (str calculated " " currency))))

                (print-vat {:amount 100 :currency "PLN"})
            

Java Interop


; ClojureScript
(.toUpperCase "fred") ; -> "FRED"
(.getName String) ; -> "java.lang.String"
(.-x (java.awt.Point. 1 2)) ; -> 1
Math/PI ; -> 3.141592653589793

// Java
"fred".toUpperCase() // -> "FRED"
String.getName() // -> "java.lang.String"
java.awt.Point(1, 2).x // -> 1
Math.PI

Type Hints


                ; ClojureScript
                (defn len [x]
                 (.length x))

                (defn len2 [^String x]
                 (.length x))

                user=> (time (reduce + (map len (repeat 1000000 "asdf"))))
                "Elapsed time: 3007.198 msecs"
                4000000

                user=> (time (reduce + (map len2 (repeat 1000000 "asdf"))))
                "Elapsed time: 308.045 msecs"
                4000000

Warn on reflection


                    ; ClojureScript
                    (set! *warn-on-reflection* true) ;-> true

                    (defn foo [s] (.charAt s 1)) ; -> Reflection warning, line: 2 - call to charAt can't be resolved.

                    (defn foo [^String s] (.charAt s 1))

JavaScript Interop

A visual overview of the similarities and differences between ClojureScript and JavaScript

Hiccup


                ; ClojureScript
                [:a {:href "http://github.com"} "GitHub"]

                [tag & body]
                [tag attributes & body]

                
                GitHub

                ; ClojureScript
                [:div {:id "email" :class "selected starred"} "..."]
                [:div#email.selected.starred "..."]

                    [:div
                     [:p "I am a component!"]
                     [:p.someclass
                      "I have " [:strong "bold"]
                      [:span {:style {:color "red"}} " and red "] "text."]]
                

                

I am a component!

I have bold and red text.

I am a component!

I have bold and red text.

Shadow-cljs


                npx shadow-cljs watch app
            
- Good configuration defaults - npm integration - Live Reload (CLJS + CSS) - CLJS REPL

REPL


                    (shadow.cljs.devtools.api/nrepl-select :app)
                    (in-ns 'me.stasiak.starter.core)
            
proto-repl

devcards

clojure specs

core.async

Multimethod

Specter

Thank you