Here are my notes from Stuart Halloway's RuPy 2013 keynote.
My own talk yesterday also addressed immutability.
- Pedestal: Decouples client-side and serverside development.
- In Pedestal, UI drawing is step by step, you can play it forwards and backwards. Every step is an immutable value. You can do client-side dev without being connected to the serverside at all. You can have a button for the user that sends an error report with the full steps that lead to that situation. You can reproduce it fully.
False start 2: Go
Ideas in Clojure
- Data serialization format. Superficially like JSON. Different types. Four kinds of collections: lists, vectors, maps, sets.
- Not a "comma-dominated language". You may use commas to make you feel better but you'll start wondering why you did that.
- Clojure is almost entirely written in EDN. Hello World, semantically is a function, but structurally an EDN data structure.
- "I just taught you all of Clojure".
- "I'm going to sing all the operator precedence rules in Clojure", followed by silence. "And I'm done."
- EDN has generic extensibility through tags. Built-in tags like #inst for time and #uuid for UUID literals. As programmers, we're working with data and we ought to be working in data literals. Programming language can't guess all the types, Clojure/EDN makes this possible.
2. Persistent Data Structures
- In Clojure data does not go away. When you update a data structure, you get a new one that contains the old stuff.
- Immutable, maintain performance guarantees, change by functional application, full access to old data.
- Why does it matter? We have entire kilobytes of memory. But we have transient data structures that have different stuff at different times, we have to reuse since we only have 10K!
- Transient data structures means everything, everywhere sucks.
- We're still following ideas that were good in the 1970s. We have stuff now that a million times more capacious.
- Things change in the world and we need to deal with that. In Clojure, this is solved by the...
3. Unified Succession Model
- Each value is succeeded by the next.
- With in-place effects subprograms are machines. Sticking together a bunch of moving parts. It does not make sense if you have a lot of memory.
- Refs: All new memory uses new places. Mapping back to OO: We really respect the notion of constructors. Refer to a point-in-time value.
- A series of values: New York Yankees have a set of players, then another set of players, then another. Different values inside the reference at different times. Next value from previous using a function. The semantics of succession defined by the function used (e.g. swap!).
- The same model scales to a whole database. The db is an immutable value. Next version of entire database by using a succession function.
- OO mixes time semantics and data. Clojure separates data from dealing with time.
- A sequence is like an immutable iterator.
- Showing Clojure first, rest, cons. Things built on those: take, drop, iterate, cycle, repeat.
- Can be done lazily and infinitely.
- Order of a 100 functions like this on seqs. When you have them, no need to write new ones. A whole lot of busywork goes away.
- In Clojure, many things are processed as seqs. JSON, resultsets...
- Clojure sequences are thread-safe. Immutable -> composable.
- A named set of generic functions. Path to polymorphism.
- Roughly equivalent to Java interfaces.
- But. Can extend protocols to pre-existing types. Like Strings. Showing extend-type.
- Ruby programmers recognize this as monkey patching. But the important difference is that in monkey patching there's two places: The code to monkey patch and the interface you want to add. You stick it in the code mutably. Many monkey patches may compete.
- In protocols: Three places. Data, protocol, binding. The binding has its own namespace. No collision or mutable yuckiness.
- The Go stuff shown earlier was actually ClojureScript running in the browser. Ditto for the Pedestal example.
- ClojureScript brings concurrency and thread semantics to the browser.
- ClojureScript has terrific performance. Not trading away performance. Fine control over the JS generated (perfect if you need it).
- Targets the Google Closure compiler for whole-program optimization. Often optimized down smaller than similar programs written in JS, even with Clojure lib included.
- Browser-connected REPL: Work in Emacs/Vim/whatever REPL and connect it to the app in the browser. Extremely fast to try things out.
- Composing sequences to solve a problem (filter, map, count). But the intermediate "conveyor belt" has memory allocation.
- Replace with r/filter, r/map, r/reduce. Instead of composing conveyor belts, compose the functions. This could be actually done in parallel. Replace reduce with fold -> Automated parallelism using the fork/join framework. Shape of the code doesn't change when you go multicore.
- Rock/papers/scissors/lizard/spock example.
- Logic programming in Clojure or in the browser with ClojureScript.
- Functional programming forces to choose inputs and outputs, with logic programming you can choose at runtime
- Showing entire API: connect, grab the lazily realized database from the connection. When you query, it's not against the connection, but against the database.
- You don't go to the special place to make queries. You can do them anywhere.
- Cross-database joins, joining with in-memory collections. Logic programming.
- There is no infinite series of "make up a class that represents X". Single interface called entity.
- ACID transactions as functions of data. Return value of tx is the entire value of the database before and after the tx and what changed. Try doing that with ActiveRecord.
- Go to the past or to a possible future. "What would the db look like if I did this?".
- Monitor all changes in the system using a queue, from any process. This is the way to make systems with reproducable results.
- The Go blocks shown in the beginning.
- Has alt - like Unix select on steroids in a library that works anywhere, including the browser.
Showing multithreaded search, with three subsearches with timeouts. Like the famous Go example. In Clojure.
Any language can take on some of these ideas, like running in the browser
EDN, unified succession model, reducers, seqs, etc. don't work at all where mutability is the default, or are substantially harder.
If you take one message from the entire talk: In the next big language, immutability will be the default.
Know Your AngularJS Inside Out
Build Your Own AngularJS helps you understand everything there is to understand about AngularJS (1.x). By creating your very own implementation of AngularJS piece by piece, you gain deep insight into what makes this framework tick. Say goodbye to fixing problems by trial and error and hello to reasoning your way through them
- RuPy 2013: HTML Hypermedia APIs And Adaptive Web Design
- RuPy 2013: Substance D: Build Civilized Web Applications