This is a study note of the part III of the book Getting Clojure.

Ch16: Interoperating with Java

  • New instance: ClassName. args
  • Call method: .method instance
  • Access fields: .-field instance
  • Use package: import or :import
  • Use class method/field: ClassName/field args

every Clojure value is a Java object. Use class value to find the class.

class/field and .method are hardwired special forms. They are not Clojure functions. Use memfn to convert a method into a function.

Beaware of Java’s mutable data type. Use vec to convert a Java vector into an immutable Clojure vector.

Ch17: Threads, Promises, and Futures

Dynamic vars are local and thread safe.

Use promise function to create a promise. Use deliver to set a value. Use deref or @ to get the value in a block mode, better with a timeout.

Use future to evaluate an expression in a thread pool.

pmap runs in parallel mode.

Ch18: State

atom, ref and agent are mutable container for a value that march from one value to the next by supplying a function: a function that take the old value and produce the new value.

Atoms are simple, standalone and resolving conflicts by reevaluating the update function. Refs can be updates in a batches. Agents queue up updates that execute only once in a asynchronous mode. You can check the agent status.

Ch19: Read and Eval

Clojure is homoiconic because the same syntax is used for both code and data. Homoiconicity makes code analysis easy.

read reads code-like data from a character stream. read-string reads from a string.

eval compile and runs the code-like data. It runs in a different environment.

with-meat or ^:metadata creates metadata to symbols. Use (meta var) to get metadata.

Ch20: Macros

Use backslash to define syntax quoting that works like a code template. ~name marks a placeholder.

Use name# for local symbol. Use ~@col to expand a collection without an extra ().

Macro has two types of code: regular code and codelike data. There are two processing phases: expanding phase and execution phase.

Macro should be only used directly, not as argument for higher functions.

The main benefits of macro are lazy evaluation and less code repetition.