(operator operand1 operand2 … operandn)
NOTE: The above expression is called a “form” (it is common to all Lisps)
OPINION: Should just call 'em expressions and be done with it
nil
true
, false
1
, floats 1.2
, ratios 1/2
"only double quotes work"
\a
\b
\c
#"regular-expression-here"
:colon-prefixed-symbols
nil
+
map
Maps (Dicts/Objects/Hashes): {:keyword-keys "value can be anything"}
(get {:key "value"} :key "default")
=> Lookup by key, “default” if not found(assoc some-map :key "V")
(assoc some-map :key "U")
(dissoc some-map :key)
(contains? some-map :key)
=> true | false(find some-map :key)
=> [:key “U”](keys some-map)
(vals some-map)
(merge map-one map-two)
(get-in {:a {:b "value"}} [:a :b])
=> Nested(:key {:key "value"} "default")
== ({:key "value"} :key)
== "value"
Records (Alternatives to maps for domain specific data with “type”):
(defrecord Name [field1 field2 field3])
(def inst1 (->Name val1 val2 val3))
(def inst2 (map->Name {:field1 val1 :field2 val2 :field3 val3}))
Vectors (Arrays): [1 2 3 "anything" :goes]
(get [1 2 3] 0)
=> Lookup by index(conj [1 2 3] 4)
=> Adds to end of vectorLists (Linked Lists): '(1 2 3 "anything" :goes)
(first '(1 2 3))
=> 1(rest '(1 2 3))
=> 2 3(pop '(1 2 3))
=> 2 3(peek '(1 2 3))
=> 1(nth '(1 2 3) 0)
=> Lookup by iterating(conj '(1 2 3) 4)
=> Adds to start of listSets: #{"some" :values 1 1/4}
(conj #{:a :b} :c)
=> :a :b :c(disj #{:a :b :c} :c)
=> :a :b(contains? #{1 2 3} 2)
=> Check inclusion, returns true/falseget
and :key
lookup too
(are_forms? x y z)
=>true
(= x y)
(or x y)
=> First truthy or first false/nil(and x y)
=> First false/nil or last truthy(do x y z)
def
is all where all bindings start
(def const "value")
=> symbol const
is now bound to "value"
(defn fun-name "document string" [param & rest] (print "This is some form") {:last-form "returned"})
(fn [arg] (print arg))
== #(print %)
==> anon fn
fn
has closure over surrounding lexical scope(let [name value] (code that uses name))
=> let
creates bindings in lexical scope
If-else: (if <cond> <then> <else>)
=> all things inside <>
are individual forms
else
then returns nil
on false
do
to add more than one expression in the branchesWhen: (when <cond> <form1> <form2> <form3>)
if
and do
Cond: (cond <condition1> <expression1> <condition2> <expression2>)
=> Successively check each condition and evaluate corresponding expression if true
Cond-else: (cond <> <> <> <> :else <expression>)
=> :else
always evaluates to true. Using the word “else” is a convention.
Case: (case <var> <case_1_literal> <expression> <case_2> <expression>)
Case-else: (case <var> <> <> <> <> <default expression if no match>)
For: (for <[bindings]> <expression>)
Loop + Recur: (loop <[bindings]> (<expr> (recur <[bindings]>)))
Fn + Recur: (defn name <[bindings]> (<expr> (recur <[bindings]>)))
recur
must be the last expressionwith
in python)