Reputation: 1977
I am beginning learning clojure. Coming majorly from Java and some scripting languages, the code as data part of clojure (and all functional languages, I assume) is not so clear.
Starting from the first pages of the book I see forms. And I see it mostly associated with data, like #{1 2}
. But in some other places I saw Boolean
labelled as form
.
Now, I was under the assumption that false
is a form of type Boolean
, but I didn't see type
being mentioned more than a few times, so I am confused.
Can someone give me a push to understand the concept of forms and also give me a push so that I can understand code as data part of the language?
Upvotes: 3
Views: 303
Reputation: 13483
Are clojure forms data or type?
- data
A Clojure form is a piece of code viewed as data.
Clojure forms have a chemistry. The elements are things like
42
, 3.1416
, 22/7
)"1, 2, buckle my shoe."
)a5
, freds-white-teeth
), whatever they denote. The molecules are things like
(+ 1 1)
, (reduce * (range 1 n))
)[f coll]
, [[forename surname :as name]]
)The only structures used to bind molecular forms together are Clojure's own data structures. This is what code as data means.
Clojure uses
(maps for associative binding forms).
(Leave these for now).
At the top level, we typically have def
and defn
forms. These can be many layers deep.
def
is a special form. It has its own evaluation rules.defn
looks like a special form, but it isn't.Because Clojure programs are written as Clojure data, we can write functions that
The final piece of the jigsaw is that Clojure supplies a special mode of function, called a macro, that
This turns out to be a mechanism of great power. For example, defn
is a macro that wraps a fn
form inside a def
form. A cheap and cheerful analogue is
(defmacro my-defn [name & args-and-body]
(list 'def name (cons 'fn (cons name args-and-body))))
The real defn
is considerably more complicated. But this one is enough to cope with
(my-defn twice [n] (* 2 n))
(twice 3)
;6
We can see what's going on by doing
(macroexpand '(my-defn twice [n] (* 2 n)))
;(def twice (fn twice [n] (* 2 n)))
We can even define recursive functions:
(my-defn fact [n]
(if (pos? n)
(* n (fact (dec n)))
1))
(map fact (range 1 5))
;(1 2 6 24)
Upvotes: 4
Reputation: 13483
Clojure has forms because it is a Lisp.
The rules for evaluation tell you how forms work.
For example, take a look at the source for and
. You can't do this in Java.
This answers your question for Lisps in general.
Upvotes: 6