Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting Started with ClojureScript

JSIST
September 27, 2014

Getting Started with ClojureScript

JSIST 2014
By : Üstün Özgür
http://jsist.org

JSIST

September 27, 2014
Tweet

More Decks by JSIST

Other Decks in Programming

Transcript

  1. Rationale for ClojureScript • JavaScript has reach and is very

    flexible • Lisp in C's clothing: closures, functional constructs • Not robust or good enough programming in the large • Lacks (at least for now) some features like modules, destructuring • Has quirks • Client-service Applications are on the Rise
  2. Clojure: Main Language Features and Philosophy 1. Dynamic development 2.

    Functional paradigm 3. Lisp 4. Designed to be hosted
  3. 1. Clojure is Dynamic • JavaScript has a REPL: in-browser

    and node • Clojure has a better one • Not just something you compile and run, but something with which you can interact. • Defining/redefining functions, hot-swapping code
  4. 2. (Clojure is a Lisp) • List Processing language •

    John McCarthy 1958 • Almost no syntax • Prefix notation: (operator arg1 arg2) • (my-function arg1 arg2) = myFunction(arg1, arg2) • Special forms: 
 (def x 3)
 (defn foo [a b] (+ a b))
  5. (operator arg1 arg2 …) (+ 1 2) => 3 (+

    1 2 3) => 6 (* (+ 2 3) 4) => 20 No precedence rules. Read inside out
  6. (operator arg1 arg2 …) • Some special forms like def,

    defn • No different syntax for control flow (if condition
 (+ 1 2) 
 (+ 2 3)) (while true 
 (do it))
  7. A modern Lisp
 Not that many Parentheses • Brackets [

    ] for vector data and bindings • '(1 2 3) vs [1 2 3] • Curly braces {} for maps like JS • {"name" "John" "surname" "McCarthy"} • Makes code easier to read compared to other Lisps
  8. Primitive Data Structures • Number: 1, 2e3 • String: "JsIst

    2014" • Characters: \A, \b • Regex: #"\d{3}" • Symbol: 'foo, 'bar • Keywords: :foo, :bar
  9. Composite Data Structures • List '(1 2 3) • Vector

    [1 2 3] • Map {:name "John" :surname "McCarthy"} • Set #{1 2 3} #{"Apple" "Orange"}
  10. Composite Data Structures • Composable
 [{:name "John" :surname "McCarthy"
 :hobbies

    #{"AI" "PL"}}
 {:name "Alonso" :surname "Church"
 :hobbies #{"PL" "Maths"}] • Can be used as functions
 ({:name "John"} :name) —> "John"
  11. 3. Functional Programming • Avoid mutable state • Functions first

    class • Immutable data structures • Recursive iteration instead of explicit loops • Most parts of most programs should be functional, and that programs that are more functional are more robust.
  12. Functional Programming • Pure functions, more robust code • Single

    unit to reason about • State should be concentrated in a small part of the application
  13. State management • In JS, most data is mutable by

    default a = [0, 1, 2] a.push(3) a -> [0, 1, 2, 3] • In Clojure, most data is immutable by default (def a [0 1 2]) (conj a 3) -> [0 1 2 3] a -> still [0 1 2]
  14. State management with Reference Types • Mutable data managed through

    atoms (def a (atom [0 1 2]) (swap! a conj 3) • Roughly equivalent to: (def a (conj a 3)) • a is a reference type: get the real value via @a • Have to use swap! or reset! to make changes • Explicit state changes Note: Vars are mutable to aid development
  15. Functional Programming • Main aim is to process sequence of

    values • Transform the whole collection, select a subgroup with desired properties, or generate a summary of the sequence (map times-two [0 1 2] (filter pos? [-1 0 1]) (reduce + [1 2 3]) (reduce * [1 2 3]) (map transform-fn collection) (filter predicate-fn collection) (reduce reducer-fn collection)
  16. Functional Constructs • for comprehensions like Python or CoffeeScript (for

    [i (range 10)] (* i i)) • underscore.js provides most of these in JS • mori.js is even better
  17. 4. Clojure is Hosted: 
 Easy JS interop • #js

    literal
 x = {"foo": "bar"}
 (def x #js {:foo "bar"}) • clj->js, js->clj, js-obj functions • method calls become function calls 
 
 myObject.myMethod(arg1, arg2) 
 
 (.myMethod myObject arg1 arg2)
  18. 4. Clojure is Hosted: 
 Easy JS interop • anObject.aProperty


    (.-aProperty anObject) • myobject.method1(arg1).method2(arg2) 
 
 (.. myobject 
 (method1 arg1)
 (method2 arg2))

  19. Interop with JS • js/foo to access global foo object

    • (.getElementById js/document "a-div") • document.getElementById("a-div") • functions in namespaces are accessible in JS using object access • Assuming you have myFunction in myLib namespace • window.onload = myLib.myFunction(arg1, arg2)
  20. How ClojureScript works • Actually a Clojure library that emits

    JavaScript code • Reads the code, analyzes (AST), emits JS • Then uses Google Closure compiler to create final output • Manage dependencies • Create optimized and obfuscated code • Dead code elimination * from the book "ClojureScript Up and Running" by O'Reilly
  21. Clojure constructs not found in JavaScript • protocols: a bit

    like interfaces in Java • separate implementation from interface • same function with different number of arguments (defn foo 
 ([n] (str "received a single arg" n))
 ([n m] (str "received two args" n m))) • destructuring: map multiple variables to multiple values 
 
 [name surname] ["John" "Doe"]
  22. Namespaces • Like module pattern via objects in JS !

    ! ! • Google Closure uses this format • Correspond to matching directory and files (ns 'foo.bar) (def x 3) var foo = foo || {}; foo.bar = foo.bar || {}; foo.bar.x = 3;
  23. Essence of Programming • Generating UI: Views • Managing State

    Changes: Store • Coordinating Processes: Actions • User action events • Server calls • Especially async events Web ^
  24. Managing State Changes • State should be as concentrated as

    possible • Push towards edges • Do not litter your codebase with state • Idiom: Use a single atom to hold application state • Some local state is allowed for temporary things like hover
  25. Om: Library for Building UIs • Functional UI in a

    stateful DOM • Actually a wrapper around Facebook's React • Most state is stored at the top-level in a single atom • The UI is built using this single atom • Each component gets a path to its data Data locality via cursors (path to specific data)
  26. Manage Processes • Event buses: event oriented programming • Channels:

    Communicating Sequential Processes • Put a value to a channel • Take a value from a channel • Sequential Processes • Process A & Process B • A & B communicate through a channel • Rendezvous based unlike event buses • A waits for B, B waits for A
  27. Manage Processes • Main Problem: name = raw_input("What is your

    name") print "Hello", name • raw_input blocks • In JS, we use callbacks, the equivalent would be: raw_input("What is your name", 
 function (name) {
 console.log("Hello", name); }) • No longer blocking, but we lose the simpler flow
  28. Solutions in JS • Promises sort of fix this: •

    raw_input("What is your name")
 .done(function (name) { 
 console.log("hello", name)}); • Becomes harder when multiple processes have to be managed. ES6 generators (yield, like in Python a possible solution)
  29. Clojure's approach: core.async • (def my-channel (chan)) • (defn event-handler

    []
 (put! my-channel 1)) • (go (while true
 (<! my-channel)
 (print "data received"))
  30. Chan Process 1 Process 2 puts takes (go (while true


    (<! my-channel)
 (print "data received")) button click Parks the loop (pauses)
 until we take from the chan
  31. How to Get Similar Functionality in JavaScript • Code architecture:

    React + Flux to manage state. • Explicit and managed state changes • Immutable data structures: mori.js, immutable.js • Functional constructs: mori.js, underscore.js • Namespaces: browserify or webpack • core.async: ES6 generators, or promises
  32. Common Concerns • How big is the final output? •

    Is it fast enough? • How is the tooling support? • Debugging
  33. Conclusion • ClojureScript has saner defaults and better functional programming

    support • Knowing ClojureScript makes you a better developer even if you do not use it for production • Still in assess phase in Thoughtworks Technology Radar. (Clojure in Adopt phase) • Promising, but tooling still weak. IntelliJ Idea Cursive is getting better.