Inside Clojure with Rich Hickey

No commas, semi-colons.
Prefix notation: the operator comes first, then arguments.
By default, the interpretation of things in parens is a list.

(+ 1 2) // 3
(list 1 2 3) (1 2 3)// list of three things
(vector 1 2 3) [1 2 3] // vector of three numbers
{:a 1 :b 2} // map with two entries
{"a" [1 2] [1 2] "1 2"} // maps are arbitrarily nestable: can map to different types
#{ A B C} // sets. Duplicates get washed out, no order

A list differs from a vector in the complexity characteristics of different operations.
Insertion characteristic adding at the front is O(1) whereas looking in middle or adding at the end is O(n) (linear time).

A list is a singularly linked list where efficient to add to front in construct (cons) operation.
However, looking up fourtenth item in list is linear operation because have to walk the chain.
A vector is efficient to add at the end, or lookup by index.

Vectors and maps are functions. To lookup, call it on its index:
([1 2 3] 0) // returns 1

1 is number literal. :a is a keyword literal. A is a symbol literal, if want the value can quote it: 'A. "A" is a string.
A symbol might stand for something else but a keyword only ever designates itself.

There are literals for all the data structures and you write a program by writing data structures.

The important thing about lisps is the language is not defined in terms of syntax, rather characters.

Two phase syntax:
Source Code (text) -> Reader (outputs in memory data structure) -> Evaluator / Compiler

For example, Reader will read (+ 1 2) is a list.

Can also write program that produces data, and pass to Evaluator / Compiler. Evaluator can then request data.
This is how macros work.

Lists treated as calls, most the others treated as data.

cons from lisp as been abstracted in Clojure with conj which will add onto the front of anything appropriately.

(into collection (map function collection)) // works for all structures.

Interfaces exist for all things: normal Java .NET interfaces.

Can call a method on an object using ..

A persistent data structure is not merely immutable, has another special characteristic: if take immutable things and produce
new version of it, several things true:

  • old version remains accessible
  • can produce new version in compliance with whatever complexity guarantees are for that data structure
  • old and new versions will meet complexity guarantees for the structure

All data structures except list (which can meet complexity guarantee by being singularly linked list) are trees. At the leaves of trees are arrays.
Branching factor is 32 (extremely shallow). To add, just need to copy root and three nodes of trees, all others refer to previous. This is called structural sharing.

Hash array mapped tries (Bagwell).

Identities. Clojure not object oriented. Hickey worked on after experiencing challenges of building big multi-threaded systems using object orientation.

Some things that aren't working quite correctly in object orientation.

  1. Object orientation conflates indentity and value (or state). They're bound together. Value may change over time.
    This is because Object reference is essentially alias for block of memory somewhere.
    To fix, the label should be for a timeline. Timeline changes, but reference types stay the same: all they are are boxes refering to values.
    Box is a time management unit.