This is a study note of the part II of the book Getting Clojure.
Ch10: Sequence
Clojure uses a wraper method to define a set of standard functions sequence type.
(seq col)
returns a sequnce,nil
for an empty collection.- A universal interface:
first
,rest
,next
,cons
- For empty collection,
rest
returns an empty sequence;next
retrunsnil
. - Toolkit:
sort
,reverse
,partition
,interleave
,interpose
. - Richer functions:
filter
,some
,map
,comp
,for
,reduce
,sort-by
. - Other sources:
line-seq
,re-seq
. ->>
put a result at the end of teach step.->
put a result at the front of each step.conj
appends a vector and preappends a list but return the orginal collection.cons
prepends a ventor or a list and returns a sequence.
Ch11: Lazy Sequence
Laziness can save cycles and organize programs (like the REPL). Sequences without end, such as repeat
, repeatedly
, cycle
, and iterate
must be lazy.
Lazy functions: take
, map
, interleave
, interpose
, cons
.
Behind the scenes, lazy-seq
uses Macro
to wrap its argument in an anonymous function.
Use doall
and doseq
run down lazy sequnce and access elements for all or one by one.
Don’t uses count
, sort
, reduce
with unbounded sequences.
Ch12: Destructuring
- Destructuring works with
let
and function parameters. - Take from the start or skip using
_
. - Use
[]
to delimit any sequential data type. - Use
[{symbol :keyword}]
to desstructure a map. - Use `
[{:keys [symbol1 symbol2]}]
to get values for selected keywords. - Use
:as symbol
to fetch the original value. - Use
:or
for missing values.
Ch13: Records and Protocols
Map is slow and too generic. Records are maps with predefined keys and functions working with maps also work with records.
The benefits of records are 1) providing types 2) better performance.
Protocols defines an interface that has a set of methods. The protocol is independent defined – this is a desired feature because it decouples data and functions. It can be defined independently for any type using extend-protocol
. Better to put each protocol in its own namespace to avoid function name confliction.
Comparison with multimethods:
- single function vs. an interface with a set of functions.
- dispatch on a record type vs. arbitrary dispatch mechanism.
Use reify
to define one-off protocol implementation.
Ch14: Tests
deftest
andtesting
to define a set and subset of tests.- Propety-base testing generates tests for checking properties.
Ch15: Spec
clojure.spec
validate theshape
, not type of data.- A
spec
specifies a pattern. - Functions:
s/and
,s/or
,s/coll-of
,s/cat
,s/keys
,s/?
. - Use
s/def
to register ands/valid
to run. s/explain
ands/conform
explians why.s/fdef
defines function spec.test.check
enables spec-driven tests.