How does Clojure loop form works? - clojure

I am new to Clojure an Functional Programming both.
I tried my best, understanding the loop construct.
I can use it, I can look at a code written with it and tell the output but what I dont understand is,How does it work ?
is it same as writing an anonymous function with parameters and then keeping recur at the tail with same arity and new values ?
is it an inbuilt macro or something for it ?

Actually, loop is not a function or a macro. It is a special form. It works just like let (which is also a special form) except that it acts as a target for recur.
One way to differentiate functions, macros, and special forms is to examine how their arguments are evaluated:
Function arguments are always evaluated, and then the results are passed to the function.
Macro arguments are not evaluated until the macro expands to a new unevaluated form.
Special form arguments are not evaluated when passed, but the special form may or may not choose to evaluate them internally.

dbyrne's answer is all true, and good, but I'd like to address your further question "Is it the same as writing an anonymous function with parameters and then recur at the tail with same arity and new values?". Yes, it is exactly like that:
(loop [x 1, y 2]
(if (whatever x y)
(recur (inc x) (dec y))
(* x y)))
is functionally identical to
((fn [x y]
(if (whatever x y)
(recur (inc x) (dec y))
(* x y)))
1 2)
If loop didn't exist, you could write it as a simple macro that emits this sort of form, but the compiler has a special loop form which is faster.
(defmacro loop [bindings & body]
(let [bindings (partition 2 bindings)]
`((fn [~#(map first bindings)]
(do ~#body))
~#(map second bindings))))

Related

Idiomatic no-op/"pass"

What's the (most) idiomatic Clojure representation of no-op? I.e.,
(def r (ref {}))
...
(let [der #r]
(match [(:a der) (:b der)]
[nil nil] (do (fill-in-a) (fill-in-b))
[_ nil] (fill-in-b)
[nil _] (fill-in-a)
[_ _] ????))
Python has pass. What should I be using in Clojure?
ETA: I ask mostly because I've run into places (cond, e.g.) where not supplying anything causes an error. I realize that "most" of the time, an equivalent of pass isn't needed, but when it is, I'd like to know what's the most Clojuric.
I see the keyword :default used in cases like this fairly commonly.
It has the nice property of being recognizable in the output and or logs. This way when you see a log line like: "process completed :default" it's obvious that nothing actually ran. This takes advantage of the fact that keywords are truthy in Clojure so the default will be counted as a success.
There are no "statements" in Clojure, but there are an infinite number of ways to "do nothing". An empty do block (do), literally indicates that one is "doing nothing" and evaluates to nil. Also, I agree with the comment that the question itself indicates that you are not using Clojure in an idiomatic way, regardless of this specific stylistic question.
The most analogous thing that I can think of in Clojure to a "statement that does nothing" from imperative programming would be a function that does nothing. There are a couple of built-ins that can help you here: identity is a single-arg function that simply returns its argument, and constantly is a higher-order function that accepts a value, and returns a function that will accept any number of arguments and return that value. Both are useful as placeholders in situations where you need to pass a function but don't want that function to actually do much of anything. A simple example:
(defn twizzle [x]
(let [f (cond (even? x) (partial * 4)
(= 0 (rem x 3)) (partial + 2)
:else identity)]
(f (inc x))))
Rewriting this function to "do nothing" in the default case, while possible, would require an awkward rewrite without the use of identity.

Simple thread macro implementation

Very new to clojure so might be a noob question but here it is. So I read that the -> macro will invoke functions in sequence and I understand how this works.
(-> (+ 1 2) (* 10)) which results in 30
But why does this not do the same?
(defn testing-> [a b]
(list a b)
first)
This returns a function first and not "a" when called as (testing-> "a" "b"). What am I missing here? Using it in the wrong way?
the -> needs to be in the body of the function. it's not magic attributed to functions ending with -> but literally a macro whose name is -> which takes a sequence of things to do and produces a new expression with the same things nested each inside the next:
(defn testing [a b]
(-> [a b]
list
first))
in this exampel, when the -> macro runs it produces a new expression which looks like:
(defn testing [a b]
(first (list [a b])))
For another example, when you call -> with the arguemnts (+ 1 2) (* 10) it returns the expression (* (+ 1 2) 30) which is then evaluated as normal Clojure code.
PS: a macro is a function which takes a Clojure expression and produces another Clojure expression. These run In the middle of the compilation cycle and you can see what they are doing with the macroexpand-1 function.
A macro is something that restructures its input before it gets compiled.
user> (macroexpand '(-> (+ 1 2) (* 10)))
(* (+ 1 2) 10)
testing-> is a function, not a macro, so it does not restructure the input. You would need to rearrange the input forms before evaluation to get a behavior similar to ->. Every valid form needs to be translated into the standard clojure syntax at compile time, which is done via reader-expansion and macro-expansion.
Macro construction uses standard Clojure functions, but the semantics are somewhat unique (a macro should return the form that will be used at runtime). You can use the clojure.repl/source macro to see how various macros are implemented.
Any operations you need can be expressed as functions, and general creating macros should be avoided unless you need a new syntax.

Why LET doesn't work with VECTOR?

Instead of
(let [x 1] (my-expression))
I'm trying to use:
(let (vector x 1) (my-expression))
Don't ask why, I just like normal brackets more. But Clojure says:
let requires a vector for its binding in ...
What's wrong?
The let special form binding form is required to be a vector literal not just an expression that would evaluate to a vector.
Why? Roughly stated, the expression must be compiled before it can be evaluated. At compile-time (vector x 1) will not have been evaluated to a vector, it will just be a list. Indeed if it were to be evaluated, the arguments of vector would be evaluated, meaning x would have to be resolved. But, you don't want x to be resolved, you want it bound.
let requires a vector for it's bindings (at compile time) so trying to put a vector functional call in its place won't work (as that will only produce a vector at runtime).
However you can make your own let with a bit of macro-fu:
(defmacro mylet [bindings & exprs]
`(let ~(vec bindings) ~#exprs))
(mylet (x 1) (inc x))
=> 2
Have a look at the source for the let macro
(defmacro let
"binding => binding-form init-expr
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein."
{:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
[bindings & body]
(assert-args let
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "an even number of forms in binding vector")
`(let* ~(destructure bindings) ~#body))
You'll notice that the bindings argument is not evaluated when the macro tries to ensure it was given correct arguments via assert-args.
At the point when clojure evaluates (vector? bindings) , bindings is a form (list) containing a fn as the first element followed by it's arguments and therefore is not a vector at that point.
This code, for example, does work:
(eval `(let ~(vector 'a 1) (println ~'a)))
which means you could write your own let macro that accepts a list instead of a vector. This would be quite bad for your overall Clojure experience and I wouldn't advise it.

Difference between using list and back tick in macros

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)))

How to read mentally Lisp/Clojure code

Thanks a lot for all the beautiful answers! Cannot mark just one as correct
Note: Already a wiki
I am new to functional programming and while I can read simple functions in Functional programming, for e.g. computing the factorial of a number, I am finding it hard to read big functions.
Part of the reason is I think because of my inability to figure out the smaller blocks of code within a function definition and also partly because it is becoming difficult for me to match ( ) in code.
It would be great if someone could walk me through reading some code and give me some tips on how to quickly decipher some code.
Note: I can understand this code if I stare at it for 10 minutes, but I doubt if this same code had been written in Java, it would take me 10 minutes. So, I think to feel comfortable in Lisp style code, I must do it faster
Note: I know this is a subjective question. And I am not seeking any provably correct answer here. Just comments on how you go about reading this code, would be welcome and highly helpful
(defn concat
([] (lazy-seq nil))
([x] (lazy-seq x))
([x y]
(lazy-seq
(let [s (seq x)]
(if s
(if (chunked-seq? s)
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
(cons (first s) (concat (rest s) y)))
y))))
([x y & zs]
(let [cat (fn cat [xys zs]
(lazy-seq
(let [xys (seq xys)]
(if xys
(if (chunked-seq? xys)
(chunk-cons (chunk-first xys)
(cat (chunk-rest xys) zs))
(cons (first xys) (cat (rest xys) zs)))
(when zs
(cat (first zs) (next zs)))))))]
(cat (concat x y) zs))))
I think concat is a bad example to try to understand. It's a core function and it's more low-level than code you would normally write yourself, because it strives to be efficient.
Another thing to keep in mind is that Clojure code is extremely dense compared to Java code. A little Clojure code does a lot of work. The same code in Java would not be 23 lines. It would likely be multiple classes and interfaces, a great many methods, lots of local temporary throw-away variables and awkward looping constructs and generally all kinds of boilerplate.
Some general tips though...
Try to ignore the parens most of the time. Use the indentation instead (as Nathan Sanders suggests). e.g.
(if s
(if (chunked-seq? s)
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
(cons (first s) (concat (rest s) y)))
y))))
When I look at that my brain sees:
if foo
then if bar
then baz
else quux
else blarf
If you put your cursor on a paren and your text editor doesn't syntax-highlight the matching one, I suggest you find a new editor.
Sometimes it helps to read code inside-out. Clojure code tends to be deeply nested.
(let [xs (range 10)]
(reverse (map #(/ % 17) (filter (complement even?) xs))))
Bad: "So we start with numbers from 1 to 10. Then we're reversing the order of the mapping of the filtering of the complement of the wait I forgot what I'm talking about."
Good: "OK, so we're taking some xs. (complement even?) means the opposite of even, so "odd". So we're filtering some collection so only the odd numbers are left. Then we're dividing them all by 17. Then we're reversing the order of them. And the xs in question are 1 to 10, gotcha."
Sometimes it helps to do this explicitly. Take the intermediate results, throw them in a let and give them a name so you understand. The REPL is made for playing around like this. Execute the intermediate results and see what each step gives you.
(let [xs (range 10)
odd? (complement even?)
odd-xs (filter odd? xs)
odd-xs-over-17 (map #(/ % 17) odd-xs)
reversed-xs (reverse odd-xs-over-17)]
reversed-xs)
Soon you will be able to do this sort of thing mentally without effort.
Make liberal use of (doc). The usefulness of having documentation available right at the REPL can't be overstated. If you use clojure.contrib.repl-utils and have your .clj files on the classpath, you can do (source some-function) and see all the source code for it. You can do (show some-java-class) and see a description of all the methods in it. And so on.
Being able to read something quickly only comes with experience. Lisp is no harder to read than any other language. It just so happens that most languages look like C, and most programmers spend most of their time reading that, so it seems like C syntax is easier to read. Practice practice practice.
Lisp code, in particular, is even harder to read than other functional languages because of the regular syntax. Wojciech gives a good answer for improving your semantic understanding. Here is some help on syntax.
First, when reading code, don't worry about parentheses. Worry about indentation. The general rule is that things at the same indent level are related. So:
(if (chunked-seq? s)
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
(cons (first s) (concat (rest s) y)))
Second, if you can't fit everything on one line, indent the next line a small amount. This is almost always two spaces:
(defn concat
([] (lazy-seq nil)) ; these two fit
([x] (lazy-seq x)) ; so no wrapping
([x y] ; but here
(lazy-seq ; (lazy-seq indents two spaces
(let [s (seq x)] ; as does (let [s (seq x)]
Third, if multiple arguments to a function can't fit on a single line, line up the second, third, etc arguments underneath the first's starting parenthesis. Many macros have a similar rule with variations to allow the important parts to appear first.
; fits on one line
(chunk-cons (chunk-first s) (concat (chunk-rest s) y))
; has to wrap: line up (cat ...) underneath first ( of (chunk-first xys)
(chunk-cons (chunk-first xys)
(cat (chunk-rest xys) zs))
; if you write a C-for macro, put the first three arguments on one line
; then the rest indented two spaces
(c-for (i 0) (< i 100) (add1 i)
(side-effects!)
(side-effects!)
(get-your (side-effects!) here))
These rules help you find blocks within the code: if you see
(chunk-cons (chunk-first s)
Don't count parentheses! Check the next line:
(chunk-cons (chunk-first s)
(concat (chunk-rest s) y))
You know that the first line is not a complete expression because the next line is indented beneath it.
If you see the defn concat from above, you know you have three blocks, because there are three things on the same level. But everything below the third line is indented beneath it, so the rest belongs to that third block.
Here is a style guide for Scheme. I don't know Clojure, but most of the rules should be the same since none of the other Lisps vary much.
First remember that functional program consists of expressions, not statements. For example, form (if condition expr1 expr2) takes its 1st arg as a condition to test for the boolean falue, evaluates it, and if it eval'ed to true then it evaluates and returns expr1, otherwise evaluates and returns expr2. When every form returns an expression some of usual syntax constructs like THEN or ELSE keywords may just disappear. Note that here if itself evaluates to an expression as well.
Now about the evaluation: In Clojure (and other Lisps) most forms you encounter are function calls of the form (f a1 a2 ...), where all arguments to f are evaluated before actual function call; but forms can be also macros or special forms which don't evaluate some (or all) of its arguments. If in doubt, consult the documentation (doc f) or just check in REPL:
user=> apply
#<core$apply__3243 clojure.core$apply__3243#19bb5c09> a function
user=> doseq
java.lang.Exception: Can't take value of a macro: #'clojure.core/doseq a macro.
These two rules:
we have expressions, not statements
evaluation of a subform may occur or not, depending of how outer form behaves
should ease your groking of Lisp programs, esp. if they have nice indentation like the example you gave.
Hope this helps.