Clojure: Forgetting the brackets
I’ve been playing around with macros over the last few days and while writing a simple one forgot to include the brackets to make it evaluate correctly:
(defmacro say-hello [person] println "Hello" person)
This macro doesn’t even expand like I thought it would:
user=> (macroexpand-1 '(say-hello blah)) blah
That seemed a bit strange to me but I eventually realised that I’d missed off the brackets around ‘println’ and the arguments following it which would have resulted in ‘println’ being evaluated with those arguments.
I was a bit curious as to why that happened so I tried the following expression without any brackets to see what would happen:
user=> println "hello" "mark" #<core$println__5440 clojure.core$println__5440@681ff4> "mark" "random"
It seems to just evaluate each thing individually and when we put this type of expression into a function definition the function will do the same thing but also return the last thing evaluated:
(defn say-hello [] println "hello" "mark")
user=> (say-hello) "mark"
A. J. Lopez pointed out that this is quite like progn in other LISPs and is the same as doing the following:
user=> (do println "hello" "mark") "mark"
do is defined as follows:
(do exprs*)
Evaluates the expressions in order and returns the value of the last. If no expressions are supplied, returns nil.
The way to write a function which passes those two arguments to ‘println’ is of course to put brackets around the statement:
(defn say-hello [] (println "hello" "mark"))
user=> (say-hello) hello mark nil