Clojure macros symbol evaluation - clojure

I'm confused with how symbols are evaluated inside the macro. I tried the following example
(defmacro fx-bad
[f x]
`(f x))
(defmacro fx
[f x]
`(~f ~x))
(let [f inc x 1] (fx f x)) ;-> 2
(let [f inc x 1] (fx-bad f x)) ;-> exception
fx macro functions correctly, whereas fx-bad throws the exception
CompilerException java.lang.RuntimeException: No such var: user/f, compiling:(/tmp/form-init2718774128764638076.clj:12:18)
Are the symbols resolving inside the macro? Why fx-bad doesn't work but fx does?
--
Edit:
Apparently the exception has something to do with namespaces. Actually no arguments are ever evaluated in the macro. ~ in the syntax quote just produces the actual string (Symbol) passed to macro, without it the symbol inside the list is returned as it is.
Interesting thing is is, if the arguments supplied to macro call and symbols inside the quoted (not syntax quoted) list have equivalent names, they doesn't have to be unquoted, they are the same symbol anyway. This is good indication, how macro takes place before the evaluation and just manipulates raw symbols which doesn't mean anything at this point.
However, with the syntax quote case is different, and exception is thrown until symbols are unquoted, even thought the expanded macro looks like a valid line of code for evaluator to evaluate. Here are some examples
(defmacro fx
[f x]
`(~f ~x))
(defmacro fx-bad
[f x]
'(f x))
(defmacro fx-very-bad
[f x]
`(f x))
`(let [f inc x 1] ~(macroexpand '(fx f x)))
`(let [f inc x 1] ~(macroexpand '(fx-bad f x)))
`(let [f inc x 1] ~(macroexpand '(fx-very-bad f x)))
(macroexpand '(fx (fn [a] a) b))
(macroexpand '(fx-bad (fn [a] a) b))
(macroexpand '(fx-very-bad (fn [a] a) b))
(let [f inc x 1] (fx f x)) ;-> 2
(let [ff inc xx 1] (fx ff xx)) ;-> 2
(let [f inc x 1] (fx-bad f x)) ;-> 2
;(let [ff inc xx 1] (fx-bad ff xx)) ;-> exception
;(let [f inc x 1] (fx-very-bad f x)) ;-> exception
--
=> #'user/fx
#'user/fx-bad
#'user/fx-very-bad
(clojure.core/let [user/f clojure.core/inc user/x 1] (f x))
(clojure.core/let [user/f clojure.core/inc user/x 1] (f x))
(clojure.core/let [user/f clojure.core/inc user/x 1] (user/f user/x))
((fn [a] a) b)
(f x)
(user/f user/x)
2
2
2
So what is actually happening here, why the exception is thrown in the case of syntax quote?

Please see full details in Clojure for the Brave & True and most other Clojure books.
Basically, the backquote creates a template, and the tilde tells the compiler which values to substitute. In Groovy, bash, & other languages, it is like substitution of variables in a string:
f = "+";
x = 1;
y = 2;
result = "(${f} ${x} y)"
result => "(+ 1 y)"
In this example, the y is not substituted. The Clojure macro equivalent would be:
(let [f '+
x 1
y 2]
`(~f ~x y) )
;=> (+ 1 y)
Since the y was not "unquoted" by a tilde, it is taken literally and is not replaced with the contents of the variable y.

Related

fix-point combinators in clojure

One of my favorite ways to test the power of a language I'm learning is to try and implement various fixed-point combinators. Since I'm learning Clojure (though I'm not new to lisps), I did the same for it.
First, a little "testable" code, factorial:
(def !'
"un-fixed factorial function"
(fn [f]
(fn [n]
(if (zero? n)
1
(* n (f (dec n)))))))
(defn !
"factorial"
[n]
(if (zero? n)
1
(apply * (map inc (range n)))))
For any combinator c I implement, I want to verify that ((c !') n) is equal to (! n).
We start with the traditional Y:
(defn Y
"pure lazy Y combinator => stack overflow"
[f]
(let [A (fn [x] (f (x x)))]
(A A)))
But of course Clojure is not nearly so lazy as that, so we pivot to Z:
(defn Z
"strict fixed-point combinator"
[f]
(let [A (fn [x] (f (fn [v] ((x x) v))))]
(A A)))
And indeed, it holds that (= ((Z !') n) (! n)).
Now comes my issue: I cannot get either of U or the Turing combinator (theta-v) to work correctly. I suspect with U it's a language limit, while with theta-v I'm more inclined to believe it's a misread of Wikipedia's notation:
(defn U
"the U combinator => broken???"
[f]
(f f))
(defn theta-v
"Turing fixed-point combinator by-value"
[f]
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
A sample REPL experience:
((U !') 5)
;=> Execution error (ClassCastException) at fix/!'$fn (fix.clj:55).
;=> fix$_BANG__SINGLEQUOTE_$fn__180 cannot be cast to java.lang.Number
((theta-v !') 5)
;=> Execution error (ClassCastException) at fix/theta-v$A$fn (fix.clj:36).
;=> java.lang.Long cannot be cast to clojure.lang.IFn
Can anyone explain
Why these implementations of U and theta-v are not working; and
How to fix them?
Your definition of theta-v is wrong for two reasons. The first is pretty obvious: you accept f as a parameter and then ignore it. A more faithful translation would be to use def style, as you have for your other functions:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] ((x x) y) z))))]
(A A)))
The second reason is a bit sneakier: you translated λz.xxyz to (fn [z] ((x x) y) z), remembering that lisps need more parentheses to denote function calls that are implicit in lambda-calculus notation. However, you missed one set: just as x x y z would have meant "evaluate x twice, then y once, then finally return z", what you wrote means "evaluate ((x x) y), then throw away that result and return z". Adding the extra set of parentheses yields a working theta-v:
(def theta-v
"Turing fixed-point combinator by-value"
(let [A (fn [x] (fn [y] (y (fn [z] (((x x) y) z)))))]
(A A)))
and we can demonstrate that it works by calculating some factorials:
user> (map (theta-v !') (range 10))
(1 1 2 6 24 120 720 5040 40320 362880)
As for U: to use the U combinator, functions being combined must change how they self-call, meaning you would need to rewrite !' as well:
(def U [f] (f f))
(def ! (U (fn [f]
(fn [n]
(if (zero? n)
1
(* n ((f f) (dec n))))))))
Note that I have changed (f (dec n)) to ((f f) (dec n)).

Clojure eval with Math functions

I'm having problems eval-ing a LazySeq returned by Deriva:
(use 'clojure.core.matrix)
(use 'com.lambder.deriva.core)
(def f1 '(cos (* x y)))
(def f2 '(sin (* x y)))
(def f [f1 f2])
(def u ['x 'y])
(def x 4)
(def y 3)
(defn jacobian [f u]
(map #(partial-derivative f %) u)
)
Returns a LazySeq
((vector (* (* -1 (sin (* x y))) y) (* (cos (* x y)) y)) (vector (* (* -1 (sin (* x y))) x) (* (cos (* x y)) x)))
Which can be successfully eval-ed using the REPL:
(eval (into [] (jacobian f u)))
Results in the correct matrix
[[1.609718754001305 2.5315618761974763] [2.1462916720017398 3.3754158349299686]]
If I put the eval inside the clj file and lein run
(defn -main
[]
(eval (into [] (jacobian f u)))
)
I get Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: sin in this context, compiling:(/tmp/form-init2786363415298022761.clj:1:113) since eval works in a different namespace.
Is there any way to include the clojure.math functions in the temporary namespace generated by eval? Or is there a better way to evaluate the expression?
Maybe you need to use java.lang.Math/sin function of java.
Consider using syntax-quote (`) instead quote (') to obtain fully qualified symbols that you can later eval:
's
=> s
`s
=> user/s
See more about quoting here:
https://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html

Writing the Lp norm function

I'm attempting to write the Lp norm function as to generalize the standard L2 norm (Euclidean distance) used. Here is what I have come up with so far, given how I had written the L2 norm:
(defn foo [a b p]
(reduce + (map (comp (map #(power a %) p) -) a b)))
However I am getting the error ClassCastException whenever I try to implement this function. Part of the interim code is from a previously asked question Raising elements in a vector to a power where the following code was provided:
(defn compute [exp numbers]
(map #(power exp %) numbers))
Consider factoring your code.
First define the p-norm
(defn p-norm [p x]
(if (= p :infinity)
(apply max (for [xi x] (Math/abs xi)))
(Math/pow
(reduce + (for [xi x] (Math/pow xi p)))
(/ 1 p))))
And then use the p-norm to define your p-metric
(defn p-metric [p x y]
(p-norm p (map - x y)))
Example
(p-metric 2 [0 0] [3 4])
;=> 5.0
(p-metric :infinity [0 0] [3 4])
;=> 4
Your inner (map):
(map #(power a %) p)
Returns a sequence and you can't feed that to (comp). 'comp' is for 'Function Composition'.
In the REPL:
(doc comp)
clojure.core/comp
([] [f] [f g] [f g h] [f1 f2 f3 & fs])
Takes a set of functions and returns a fn that is the composition
of those fns. The returned fn takes a variable number of args,
applies the rightmost of fns to the args, the next
fn (right-to-left) to the result, etc.
Start breaking your code into smaller steps. (let) form is quite handy, don't be shy to use it.

Can clojure evaluate a chain of mixed arity functions and return a partial function if needed?

Suppose you have three functions of arity 1, 2 and 3 as below:
(defn I [x] x)
(defn K [x y] x)
(defn S [x y z] (x z (y z)))
Does clojure have an evaluation function or idiom for evaluating:
(I K S I I) as (I (K (S (I (I)))))
returning a parital function of arity 2?
I am considering creating a macro that can take the simple function definitions above and expand them to multi-arity functions that can return partial results. I would not want to create the macro if there is already a built in or idiomatic way to accomplish this.
Here is what the expanded macros would like for the above functions:
(defn I
([x] I x)
([x & more] (apply (I x) more)))
(defn K
([x] (partial K x))
([x y] x)
([x y & more] (apply (K x y) more)))
(defn S
([x] (partial S x))
([x y] (partial S x y))
([x y z] (x z (y z)))
([x y z & more] (apply (S x y z) more)))
I'm not sure I fully understand what you are trying to do, but the comp function is useful for doing this kind of "function chaining" you seem to be talking about. For example:
user> ((comp vec rest list) 1 2 3 4 5)
=> [2 3 4 5]
Which is equivalent to:
user> (vec (rest (list 1 2 3 4 5)))
=> [2 3 4 5]
In your case, if you have the list (I K S I I), and you want to evaluate it as (I (K (S (I (I))))), I would use (reduce comp ...), but you could also use (apply comp ...).
user> ((reduce comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]
user> ((apply comp [vec rest list]) 1 2 3 4 5)
=> [2 3 4 5]
You may also be interested in the -> or ->> macros. These macros nest their arguments sequentially into the next arguments. The -> macro will nest into the first position of the next expression, whereas the ->> macro will nest into the last position of the next expression. If the "next thing" is a function, both will behave the same, and form an expression of (function nested-things-so-far), and continue along.
Really, examples are best:
(-> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- (+ 1 10) 100))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> -88
(->> 1 (+ 10) (- 100) inc)
;//Expands to...
(inc (- 100 (+ 10 1)))
;//Evaluating in the REPL...
user> (-> 1 (+ 10) (- 100) inc)
=> 90
However, it seems more like you want to do something involving auto-currying (although, again, I don't think I fully understand), and for that I don't know of anything pre-existing built-in way.

Clojure: How can I bind a variable?

I have the following defined in clojure:
(def ax '(fn x [] (+ 1 z)))
(let [z 4]
(str (eval ax))
)
:but instead of returning :
5
: I get :
Unable to resolve symbol: z in this context
: I have tried changing "let" to "binding" but this still does not work. Does anyone know what is wrong here?
Making the smallest possible changes to your code to get it to work:
(def ^:dynamic z nil)
(def ax '(fn x [] (+ 1 z)))
(binding [z 4]
(str ((eval ax)))
)
The two changes are defining z as a dynamic var, so that the name resolves, and putting another paren around (eval ax), because ax is returning a function.
A little bit nicer is to change the definition of ax:
(def ^:dynamic z nil)
(def ax '(+ 1 z))
(binding [z 4]
(str (eval ax))
)
So evaluating ax immediately gets the result you want, rather than returning a function that does it.
Nicer again is to skip the eval:
(def ^:dynamic z nil)
(defn ax [] (+ 1 z))
(binding [z 5]
(str (ax))
)
But best of all is to not have z floating around as a var, and pass it in to ax as Mimsbrunnr and Joost suggested.
The short answer is don't use eval. You almost never need to, and certainly not here.
For example:
user> (defn ax [z]
(+ 1 z))
#'user/ax
user> (let [f #(ax 4)]
(f))
5
Right so I'm not entirely sure what you are trying to do here.
I mean this works, though it's not using eval it's defining x to be the function (fn [ x ] (+ x 1))
> (def x #(+ 1 %))
#'sandbox102711/x
> (x 4)
5
In the end, eval is not something you should be using. As a Lisp Cljoure's support for lambda abstraction and macros ( see the fn definition above ) should remove the need.