2. About Clojure
• A
dynamic,
predominantly
functional
descendent
of
Lisp
• Runs
on
the
JVM
(and
on
JavaScript
&
CLR)
• Multithreading-‐friendly:
Immutable,
thread-‐safe
data
structures
with
value
semantics;
Software
Transactional
Memory
• Compiled
but
dynamic:
Anything
you
can
do
at
compile
time,
you
can
do
at
runtime
• Code-‐as-‐data
:
“homo-‐iconicity”
&
metaprogramming
• And
...
polymorphism,
reactive
agents,
optional
type
hinting,
constant-‐space
recursive
looping
3. Looks like Lisp:
(ns
fizzbuzz.core)
!
(defn
fizzbuzzat
[i]
(cond
(=
0
(rem
i
15))
"fizzbuzz"
(=
0
(rem
i
3))
"fizz"
(=
0
(rem
i
5))
"buzz"
:else
i))
(defn
fizzbuzz
[n]
(take
n
(map
fizzbuzzat
(iterate
inc
1))))
!
!
(fizzbuzz
16)
;;Result: (1 2 "fizz" 4 "buzz" "fizz" 7 8 "fizz"
"buzz" 11 "fizz" 13 14 "fizzbuzz" 16)
Reading Lisp!
Lisp has 1 main structure - the
list.
Evaluate a list by taking the first
item as a function; and all the
rest as parameters.
namespace fizzbuzz.core
define function fizzbuzzat with parameter: i
Condition: if i divided by 15 has remainder
0, then return “fizzbuzz”; else if i divides by 3
return fizz; else if i divides by 5 return buzz;
else return i
define function fizz buzz with parameter n
take: take just the first n of the
following (presumably long) sequence
map: change each item in the
following sequence by applying the
function fizzbuzzat to it. Return the
sequence of changed items
It all starts here:
iterate means: take the seed value of 1; apply the function inc (for increment-by-1)
to it; then apply inc to that; then again forever. This gives us the (infinite ) sequence
1,2,3,4,5,6,… etc
5. Immutability &
Value types as the norm
(ns
eg.core)
!
(defn
try-‐to-‐mutate
[
x
]
(let
[x
(conj
x
’LOTS)]
;;
joins
‘LOTS’
to
x
x))
(let
[x
[1
2
3]]
(try-‐to-‐mutate
x
)
(print
"x
is
:
"
x
"n"
))
;;
result:
“x
is
:
[1
2
3]”
!
;;
State
is
a
series
of
immutable
values
over
;;
time
function try-to-mutate will compile and
run, but won’t actually mutate x. The x
created by (let [x …] will be a new x,
which hides, not changes, the parameter
also called x
1. let x be [1,2,3]
2. call try-to-mutate on x
3. print it.
Behold. x is still [1,2,3]. There is no
syntax for changing a value.
6. Meta-programming
& macros
;;A
simple
example
looks
just
like
a
function
!
(defmacro
hello
[x]
(str
"Hello,
"
x))
!
;;
But
macros
extend
the
compiler.
;;
You
can
add
new
keywords,
constructs
and
;;
grammar
to
the
language
!
(defmacro
unless
[condition
&
forms]
`(if
(not
~condition)
~@forms))
!
(unless
(<
age
18)
(applytojoin
name
email
))
macros in lisp-languages are not weedy things as in
other languages. They can change the language
extensively, adding new keywords and new syntax
7. Software transactional
memory
;;
Very
like
database
transactions
with
transaction
;;
isolation
level
set
to
Snapshot.
;;
A
threads
sees
the
'snapshot'
of
all
values
that
were
;;
there
when
the
transaction
started.
No
locks
are
used,
;;
it’s
all
optimistic
using
'row
versions’
;;
and
will
retry
repeatedly
if
a
collision
occurs
;;
Transactions
are
of
course
ACID
(in
memory)
!
(def
myEntity
(ref
["Initial
Value"
1
2
3]))
!
(ref-‐set
myEntity
["Very
new
value"])
;;
throws
an
IllegalStateException,
no
transaction
running
!
;;
Use
dosync
to
wrap
it
in
a
transaction
(dosync
(ref-‐set
myEntity
["New
Value"
4
5
6])
)
8. Comments on OO/FP
• “Mutable
Shared
State
is
the
new
spaghetti
code”
• “OO
was
born
of
simulation
&
now
used
for
everything,
even
when
inappropriate”
• “An
identity
is
an
entity
that
has
a
state,
which
is
its
value
at
a
point
in
time.
And
a
value
is
something
that
doesn't
change.”
• “It
is
better
to
have
100
functions
operate
on
one
data
structure
than
to
have
10
functions
operate
on
10
data
structures.”
-‐
Alan
J.
Perlis
• You
need
Entities/Identity
much
less
than
you
think
-‐
90%
of
the
time,
values
are
all
you
really
want
• OO
hides
state
away.
FP
pushes
state
out:
it’s
an
injected
dependency.
quotes
in
quotes
are
by
Rich
Hickey
9. Clojure
!
Your
first
10
minutes:
http://tryclj.com
!
The
next
10
hours:
http://
clojurescriptkoans.com
http://clojurekoans.com
google://clojure+xxx