Are the -> and ->> macros only to make the code more readable or they have also other specific functions?
The thread-first (->) and thread-last (->>) are there to make code more readable. But that's already pretty important !
It allows to un-nest function calls (example taken from clojuredocs) :
;; Arguably a bit cumbersome to read:
user=> (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " "))
"X"
;; Perhaps easier to read:
user=> (-> "a b c d"
.toUpperCase
(.replace "A" "X")
(.split " ")
first)
It also allows you to put the emphasis on something. For instance, consider :
(-> {... }
...
...
(count))
(count (...(... {...})))
In the first example, it is very clear that you start with a map, and then do something to it. In the second, it is clear that you count something.
The preference depends on what you want to put forward.
Also, the choice of -> vs ->> is a clear visual indicator : are you operating or not on collections ? This is made immediately obvious (this is a convention in Clojure to have the collection as a last parameter).
So yes, it is "only" readability, but that is a very important part of building programs, and Clojure gives you tools to make your code read naturally. When choosing one solution, I try to consider the way Clojure will be read.
Related
How in Clojure process collections like in Java streams - one by one thru all the functions instead of evaluating all the elements in all the stack frame. Also I would describe it as Unix pipes (next program pulls chunk by chunk from previous one).
As far as I understand your question, you may want to look into two things.
First, understand the sequence abstraction. This is a way of looking at collections which consumes them one by one and lazily. It is an important Clojure idiom and you'll meet well known functions like map, filter, reduce, and many more. Also the macro ->>, which was already mentioned in a comment, will be important.
After that, when you want to dig deeper, you probably want to look into transducers and reducers. In a grossly oversimplifying summary, they allow you combine several lazy functions into one function and then process a collection with less laziness, less memory consumption, more performance, and possibly on several threads. I consider these to be advanced topics, though. Maybe the sequences are already what you were looking for.
Here is a simple example from ClojureDocs.org
;; Use of `->` (the "thread-first" macro) can help make code
;; more readable by removing nesting. It can be especially
;; useful when using host methods:
;; Arguably a bit cumbersome to read:
user=> (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " "))
"X"
;; Perhaps easier to read:
user=> (-> "a b c d"
.toUpperCase
(.replace "A" "X")
(.split " ")
first)
"X"
As always, don't forget the Clojure CheatSheet or Clojure for the Brave and True.
What is the idiomatic way of printing values inside a let binding ?
When I started developing in Clojure, I wrote code in the REPL, that I then turned into simple let expressions. Being a beginner, I often made mistakes during this (simple) transformation phase.
(let [a (aFn ...)
b (bFn ... a)]
;; error above
)
So I would transform it back to something like that, basically inlining things :
(println "a is" (aFn ...))
(println "b is" (bFn ... (aFn ...)))
(let [a (aFn ...)
b (bFn ... a)]
;; ...
)
It works most of the time thanks to Clojure being nice (immutability, referential transparency..).
Now I do something along the lines of :
(let [a (aFn ...)
_ (println "a is" a)
b (bFn ... a)
_ (println "b is" b)]
;; ...
)
It is an improvement, but it still feels clumsy. What is the proper way to do this ?
You could define a print function that returns its argument:
(defn cl-print [x] (doto x (print)))
Then, it is only a matter of wrapping your expressions:
(let [a (cl-print (aFn ...))
b (cl-print (bFn ... a))]
...)
I tend to take a totally different approach. I never put print statements in my let bindings. I also think you need to be careful about calling a function just to get the value for debugging purposes. While we would like all our functions to be side-effect free, this is not always the case, so calling the funciton just to get a value to print may have unexpected results. There is also the issue of how printing values can impact on laziness and realising of lazy sequences etc.
My approach is to define some debugging functions, which I stick in a 'debug' namespace. I then call these debug functions when needed from inside the body of the function - not in the let binding section. Often, I also define a debug-level var so that I can have some control over debugging verbosity. this allows me to change one var and increase or decrease the amount of information logged/printed.
I've experimented with 'clever' macros to make debugging easier - but to be honest, these usually take more effort to get right than the benefit they provide.
I like having my debug functions in a separate namespace as this helps me ensure I've not left any debugging code in my production version - or it allows me to leave debug statements in there, but have them 'do nothing' by setting an appropriate debug level.
As mentioned by another post, using a debugger can eliminate/reduce the need to have these print statements or debug functions. However, I think debuggers can be a double edged sword as well. Too often, people get into bad debugging hapits where they rely on trace and inspect rather than thinking about and analysing exactly what is going on. This can tend to development driven by too much trial and error and not enough analysis and understanding.
You could start with something as simple as
(def debug-level 20)
(defn debug [lvl prefix val]
(if (>= lvl debug-level)
(println (str prefix ": " val)))
(defn debug1 [prefix v]
(debug 10 prefix v))
(defn debug2 [prefix v]
(debug 20 prefix v))
etc
and then just call
(debug2 :a a)
in the body of your function to have the value of a printed when debug-level is 20 or higher.
I read that data > functions > macros
Say you want to evaluate code in a postfix fashion.
Which approach would be better?
;; Macro
(defmacro reverse-fn [expression]
(conj (butlast expression) (last expression)))
(reverse-fn ("hello world" println))
; => "hello world"
;; Function and data
(def data ["hello world" println])
(defn reverse-fn [data]
(apply (eval (last data)) (butlast data)))
(reverse-fn ["hello world" println])
; => "hello world"
Thanks!
If you require different evaluation behavior for any kind of data in your code macros are your best choice because they can transform unevaluated data at compile time to the code you'd like to be evaluated instead.
Clojure has a programmatic macro system which allows the compiler to be extended by user code. Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. (http://clojure.org/macros)
The example you provide has specifically that requirement ("evaluate code in a postfix fashion") which is why a macro is the correct choice.
Your macro is better than your function: a macro is better than a function employing eval.
However, the function need not employ eval. You could write it
(defn reverse-fn [data]
(apply (last data) (butlast data)))
Then, for example, as before,
(reverse-fn [3 inc])
=> 4
On a related topic, you might find this explanation of transducers interesting.
Edit:
Notice that functions are literals, in the sense that a function evaluates to itself:
((eval +) 1 1)
=> 2
In general:
Macros have their use however; macros expand at the point they are encountered so you will have one or more code blocks being inlined in the resulting byte code. They are ideal for encapsulating High Order DSL terminologies.
Functions, on the other hand, are wonderful for reuse where you localize the purity of the function and it can be called from multiple other functions without increasing the code footprint. They are ideal for localized or global usage.
REPL behavior consideration: A single function is easier to rework without worrying about fully evaluating the entire source file(s) to ensure all macro reference expansions get updated.
Hope this helps
Simple rules are the best: Use a function if you can, a macro if you must.
At a conceptual level a macro in LISP (and dialects) take a piece of code (as list) and returns another piece of code (again as list).
Based on above principle a simple macro could be:
(defmacro zz [a] (list print a))
;macroexpand says : (#<core$print clojure.core$print#749436> "Hello")
But in clojure this can also be written as:
(defmacro zz [a] `(print ~a))
;macroexpand says : (clojure.core/print "Hello")
I am not exactly sure about the difference here and which should be the preferred way. The first one look simple as we are supposed to return list and avoid using weird characters like back tick.
No one has pointed this out yet...the difference between your 2 macros is this: your second form (using backtick)
(defmacro zz [a] `(print ~a))
is equivalent to:
(defmacro zz [a] (list 'print a))
Which is different from your first example:
(defmacro zz [a] (list print a))
Note the missing single quote -- that is why your macroexpand is different. I agree with the other people posting: using backquote is more conventional if your macro has a fairly simple 'shape'. If you have to do code walking or dynamic construction (i.e. a complex macro), then using lists and building it up is often what's done.
I hope this explanation makes sense.
Constructing lists explicitly is "simplest", in a way, because there are few core concepts you need to know: just accept a list and change it around till you have a new list. Backtick is a convenient shortcut for "templating" chunks of code; it is possible to write any macro without it, but for any large macro it quickly becomes very unpleasant. For example, consider two ways of writing let as a macro over fn:
(defmacro let [bindings & body]
(let [names (take-nth 2 bindings)
vals (take-nth 2 (rest bindings))]
`((fn [~#names]
(do ~#body))
~#vals)))
(defmacro let [bindings & body]
(let [names (take-nth 2 bindings)
vals (take-nth 2 (rest bindings))]
(cons (list `fn (vec names) (cons `do body))
vals)))
In the first case, using backtick makes it fairly clear that you're writing a function of the names containing the body, and then calling it with the values - the macro code is "shaped" the same as the expansion code, so you can imagine what it will look like.
In the second case, with just cons and list all over the place, it is a real headache to work out what the expansion will look like. This isn't always the case, of course: sometimes it can be clearer to write something without a backtick.
Another very important point was made by Kyle Burton: print is not the same as 'print! Your macro expansion should contain the symbol print, not its value (which is a function). Embedding objects (such as functions) in code is very fragile and only works by accident. So make sure your macros expand to code you could actually have written yourself, and let the evaluation system do the hard work - you could type in the symbol print, but you couldn't type in a pointer to the current value of the function print.
There's a style difference between them. Your example is very simple but in more complex macros the difference will be bigger.
For example the unless macro as defined in "The Joy of Clojure" book:
(defmacro unless [condition & body]
`(if (not ~condition)
(do ~#body)))
From the book:
Syntax-quote allows the following if-form to act as a sort of template for the expression
that any use of the macro become when it is expanded.
When creating a macro always choose the most readable and idiomatic style.
To contrast, the above code can equivalently be written like so:
(defmacro unless [condition & body]
(list 'if (list 'not condition)
(list* 'do body)))
In my experience they are equivalent. Though there may be some edge cases I'm not aware of.
#islon 's example can equivalently be written as:
To contrast, the above code can equivalently be written like so:
(defmacro unless [condition & body]
(list 'if (list 'not condition)
(list* 'do body)))
Various special characters in clojure are abbreviations for things
(quote (a b)) is the same as '(a b)
as you can see by evaluating:
user> ''(a b)
(quote (a b))
This seems to be syntax as abbreviation, which strikes me as a fine idea.
But the syntax-quote, ` , seems special. I can't think what would be equivalent to
`(a b)
I would have guessed something like (syntax-quote (a b)) , but it doesn't work, and if I've just guessed wrong, I can't find out what it's really called.
user> '`(a b)
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/a)) (clojure.core/list (quote user/b))))
Is a bit mystifying.
Presumably the reader's doing something special, maybe because it needs to know the namespaces?
Interestingly, the special syntax used in the syntax-quote does work as I expected:
user> '~a
(clojure.core/unquote a)
user> '~#a
(clojure.core/unquote-splicing a)
user> '~'a
(clojure.core/unquote (quote a))
except for this one:
user> 'a#
a#
Which I would have thought produced something like (unquote (gensym "a"))
I do realise that I'm being a bit feeble here, and should just go and read the code. If no-one fancies explaining what's going on or giving a reference, can anyone give me a hint about how to find the relevant code and what to look for?
I don't think there's a syntax-quote equivalent of the quote function.
The Clojure reader is (currently) written in Java. The SyntaxQuoteReader class in src/jvm/clojure/lang/LispReader.java in the Clojure source is probably what you'll want to read. It seems rather complex. You can see it building lists like (seq (concat ...)) there.
ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
It's common for the reader not to return straightforward Clojure code, but rather do the right thing in Java-land immediately. For example '[1 2 3] doesn't yield the Clojure code (vector 1 2 3). Maybe it could work that way somehow, but it doesn't. The reader just creates and returns the vector object itself.
Likewise, the SyntaxQuoteReader does some magic in Java immediately to resolve symbol namespaces and create gensyms itself and it returns some mangled and complicated-looking Clojure code that does the right thing, but isn't necessarily easy for a human to read. Whether it's like this because it has to be, or because it's easier to do it this way in Java, or for performance or some other reason, I don't know. Likewise I don't know if quasiquote could exist as a plain macro/special form in Clojure and doesn't, or if it couldn't exist at all. I don't see why it couldn't though.
WrappingReader in the same file is the class that handles ' (plain old quote). You can see that it just wraps whatever you pass it in a list containing the symbol quote plus your argument. It's much simpler. Note that this class also handles #, so that '#foo does return (deref foo).
This thread might shed some more light.
Edit
Here's a proof-of-concept quasiquote macro. Note that this code is relying upon and abusing Clojure internals in a horrible way. Please don't use this for anything.
user> (defmacro quasiquote [x]
(let [m (.getDeclaredMethod clojure.lang.LispReader$SyntaxQuoteReader
"syntaxQuote"
(into-array [Object]))]
(.setAccessible m true)
(.invoke m nil (into-array [x]))))
#'user/quasiquote
user> (let [x 123] `(x 'x ~x))
(user/x (quote user/x) 123)
user> (let [x 123] (quasiquote (x 'x ~x)))
(user/x (quote user/x) 123)
hiredman has implemented a fully clojure-based version of syntax-quote. Not for the faint of heart, but a good proof of concept.
You seem to have a great grasp of the macro syntax to start with so there is not too much I can add.
there is a bit of coverage on the programming clojure forums.
and you may at your leasure read the code here check out line 352