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
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
] 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
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.
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]
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
• (.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)
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
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"]
! ! • 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;
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
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)
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
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
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)
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.