Why LET doesn't work with VECTOR? - clojure

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.

Related

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.

Clojure: Apply or to a list

This question similar to say, In clojure, how to apply 'and' to a list?, but solution doesn't apply to my question. every? function returns just a boolean value.
or is a macro, so this code is invalid:
(apply or [nil 10 20]) ; I want to get 10 here, as if 'or was a function.
Using not-every? I will get just boolean value, but I want to preserve semantics of or - the "true" element should be a value of the expression. What is idiomatic way to do this?
My idea so far:
(first (drop-while not [nil 10 20])) ; = 10
you might be able to use some for this:
(some identity [nil 10 20]) ; = 10
Note that this differs from or if it fails
(some identity [false]) ; = nil
(or false) ; = false
A simple macro:
(defmacro apply-or
[coll]
`(or ~#coll))
Or even more abstract
(defmacro apply-macro
[macro coll]
`(~macro ~#coll))
EDIT: Since you complained about that not working in runtime here comes a version of apply-macro that works in runtime. Compare it with answers posted here: In clojure, how to apply a macro to a list?
(defmacro apply-macro-in-runtime
[m c]
`(eval (concat '(~m) ~c)))
Notice that this version utilizes that parameters are passed unevaluated (m is not evaluated, if this was a function, it would throw because a macro doesn't have a value) it uses concat to build a list containing of a list with the quoted macro-name and whatever the evaluation of form c (for coll) returns so that c as (range 5) would be fully evaluated to the list that range returns. Finally it uses eval to evaluate the expression.
Clarification: That obviously uses eval which causes overhead. But notice that eval was also used in the answer linked above.
Also this does not work with large sequences due to the recursive definition of or. It is just good to know that it is possible.
Also for runtime sequences it makes obviously more sense to use some and every?.

How does Clojure loop form works?

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

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

Which Vars affect a Clojure function?

How do I programmatically figure out which Vars may affect the results of a function defined in Clojure?
Consider this definition of a Clojure function:
(def ^:dynamic *increment* 3)
(defn f [x]
(+ x *increment*))
This is a function of x, but also of *increment* (and also of clojure.core/+(1); but I'm less concerned with that). When writing tests for this function, I want to make sure that I control all relevant inputs, so I do something like this:
(assert (= (binding [*increment* 3] (f 1)) 4))
(assert (= (binding [*increment* -1] (f 1)) 0))
(Imagine that *increment* is a configuration value that someone might reasonably change; I don't want this function's tests to need changing when this happens.)
My question is: how do I write an assertion that the value of (f 1) can depend on *increment* but not on any other Var? Because I expect that one day someone will refactor some code and cause the function to be
(defn f [x]
(+ x *increment* *additional-increment*))
and neglect to update the test, and I would like to have the test fail even if *additional-increment* is zero.
This is of course a simplified example – in a large system, there can be lots of dynamic Vars, and they can get referenced through a long chain of function calls. The solution needs to work even if f calls g which calls h which references a Var. It would be great if it didn't claim that (with-out-str (prn "foo")) depends on *out*, but this is less important. If the code being analyzed calls eval or uses Java interop, of course all bets are off.
I can think of three categories of solutions:
Get the information from the compiler
I imagine the compiler does scan function definitions for the necessary information, because if I try to refer to a nonexistent Var, it throws:
user=> (defn g [x] (if true x (+ *foobar* x)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: *foobar* in this context, compiling:(NO_SOURCE_PATH:24)
Note that this happens at compile time, and regardless of whether the offending code will ever be executed. Thus the compiler should know what Vars are potentially referenced by the function, and I would like to have access to that information.
Parse the source code and walk the syntax tree, and record when a Var is referenced
Because code is data and all that. I suppose this means calling macroexpand and handling each Clojure primitive and every kind of syntax they take. This looks so much like a compilation phase that it would be great to be able to call parts of the compiler, or somehow add my own hooks to the compiler.
Instrument the Var mechanism, execute the test and see which Vars get accessed
Not as complete as the other methods (what if a Var is used in a branch of the code that my test fails to exercise?) but this would suffice. I imagine I would need to redefine def to produce something that acts like a Var but records its accesses somehow.
(1) Actually that particular function doesn't change if you rebind +; but in Clojure 1.2 you can bypass that optimization by making it (defn f [x] (+ x 0 *increment*)) and then you can have fun with (binding [+ -] (f 3)). In Clojure 1.3 attempting to rebind + throws an error.
Regarding your first point you could consider using the analyze library. With it you can quite easily figure out which dynamic vars are used in an expression:
user> (def ^:dynamic *increment* 3)
user> (def src '(defn f [x]
(+ x *increment*)))
user> (def env {:ns {:name 'user} :context :eval})
user> (->> (analyze-one env src)
expr-seq
(filter (op= :var))
(map :var)
(filter (comp :dynamic meta))
set)
#{#'user/*increment*}
I know that this doesn't answer your question, but wouldn't it be a lot less work to just provide two versions of a function where one version has no free variables, and the other version calls the first one with the appropriate top-level defines?
For example:
(def ^:dynamic *increment* 3)
(defn f
([x]
(f x *increment*))
([x y]
(+ x y)))
This way you can write all your tests against (f x y), which doesn't rely on any global state.