Calling Clojure higher-order functions - clojure

If I define a function that returns a function like this:
(defn add-n
[n]
(fn [x] (+ x n)))
I can then assign the result to a symbol:
(def add-1 (add-n 1))
and call it:
(add-1 41)
;=> 42
How do I call the result of (add-n 1) without assigning it to a new symbol? The following produces this output:
(println (add-n 1))
#<user$add_n$fn__33 user$add_n$fn__33#e9ac0f5>
nil
The #<user$add_n$fn__33 user$add_n$fn__33#e9ac0f5> is an internal reference to the generated function.

Easy:
(println ((add-n 1) 41))
The output you saw is a function definition. Putting it between round brackets and adding a parameter is enough to call it.

Related

Unexpected behavior when using recur in a variadic function

I was writing an answer for this challenge, when I needed to give a recursive function an optional parameter. I ended up with something kind of equivalent to:
(defn func [a & [b?]]
(if b?
b?
(recur a a)))
My intent was for b? to act as an optional parameter. If it wasn't supplied, it would be defaulted to nil via destructuring.
Instead of running though, it gave me an error:
(func 1)
UnsupportedOperationException nth not supported on this type: Long clojure.lang.RT.nthFrom (RT.java:947)
After some debugging, I realized that for some reason the rest parameter wasn't a list as I'd expect, but just the passed number! The error was coming about because it tried to destructure the number.
I can fix it by getting rid of the wrapper list in the parameter list:
(defn func [a & b]
...
But this just looks wrong. I know the rest parameter should be a list, but b is actually just a number. If I use "unoptimized" recursion, it works as I'd expect:
(defn func2 [a & [b?]]
(if b?
b?
(func2 a a)))
(func2 1)
=> 1
Can anyone explain what's going on here?
This appears to be a known difference
; Note that recur can be surprising when using variadic functions.
(defn foo [& args]
(let [[x & more] args]
(prn x)
(if more (recur more) nil)))
(defn bar [& args]
(let [[x & more] args]
(prn x)
(if more (bar more) nil)))
; The key thing to note here is that foo and bar are identical, except
; that foo uses recur and bar uses "normal" recursion. And yet...
user=> (foo :a :b :c)
:a
:b
:c
nil
user=> (bar :a :b :c)
:a
(:b :c)
nil
; The difference arises because recur does not gather variadic/rest args
; into a seq.
It's the last comment that describes the difference.

constantly function not workint in syntax quote

If I do this:
(eval (let [f (fn [& _] 10)]
`(~f nil)))
It returns 10 as expected.
Although if I do this:
(eval (let [f (constantly 10)]
`(~f nil)))
It throws an exception:
IllegalArgumentException No matching ctor found for
class clojure.core$constantly$fn__... clojure.lang.Reflector.invokeConstructor
Since both are equivalent why is the code with constantly not working?
This question has two answers, to really get it.
First, to clarify why your eval form is not giving you the expected result in the second case, note that f has been assigned to be equal to the function (fn [& _] 10). This means when that form is evaluated, the function object is again evaluated--probably not what you had in mind.
tl;dr: f is evaluted when it is bound, and again (with ill-defined results) when the form you create is eval'd.
The reason why one (the anonymous function) works, while the other fails means we have to look at some of the internals of the evaluation process.
When Clojure evaluates an object expression (like the expression formed by a function object), it uses the following method, in clojure.lang.Compiler$ObjExpr
public Object eval() {
if(isDeftype())
return null;
try
{
return getCompiledClass().newInstance();
}
catch(Exception e)
{
throw Util.sneakyThrow(e);
}
}
Try this at the REPL:
Start with an anonymous function:
user=> (fn [& _] 10)
#<user$eval141$fn__142 user$eval141$fn__142#2b2a5dd1>
user=> (.getClass *1)
user$eval141$fn__142
user=> (.newInstance *1)
#<user$eval141$fn__142 user$eval141$fn__142#ee7a10e> ; different instance
user=> (*1)
10
Note that newInstance on Class calls that class' nullary constructor -- one that takes no arguments.
Now try a function that closes over some values
user=> (let [x 10] #(+ x 1))
#<user$eval151$fn__152 user$eval151$fn__152#3a565388>
user=> (.getClass *1)
user$eval151$fn__152
user=> (.newInstance *1)
InstantiationException user$eval151$fn__152 [...]
Since the upvalues of a closure are set at construction, this kind of function class has no nullary constructor, and making a new one with no context fails.
Finally, look at the source of constantly
user=> (source constantly)
(defn constantly
"Returns a function that takes any number of arguments and returns x."
{:added "1.0"
:static true}
[x] (fn [& args] x))
The function returned by constantly closes over x so the compiler won't be able to eval this kind of function.
tl;dr (again): Functions with no upvalues can be evaluated in this way and produce a new instance of the same function. Functions with upvalues can't be evaluated like this.

Clojure Higher-order functions take function arguments, but what is the syntax?

I am doing the closure tutorial at http://clojurescriptkoans.com and I am stuck here: http://clojurescriptkoans.com/#functions/9
It looks like this
Higher-order functions take function arguments
(= 25 ( _ (fn [n] (* n n))))
I am supposed to fill in something at the underscore to make the expression true. I have no clue what to do.
The syntax simply consists of binding the function, and then calling it.
Since this is an exercise, I will show a similar situation rather than showing the exercise's solution:
user> ((fn [f] (f "abc")) (fn [s] (str s s s)))
"abcabcabc"
here I bind the argument of the first function to f, and call f with the argument "abc".
or you can use the short-hand notation:
#(%1 5)
Higher order functions takes functions as arguments.
Defining two functions
user=> (defn multiply [n] (* n n))
#'user/multiply
user=> (defn add [n] (+ n n))
#'user/add
Defining higher order function
user=> (defn highorderfn [fn number] (fn number))
#'user/highorderfn
Calling the higher order function
user=> (highorderfn multiply 5)
25
user=> (highorderfn add 5)
10

What does this function definition in clojure code example do?

I am following along 'Clojure in Action' and I am confused by this :
(defn with-log [function-to-call log-statement ]
(fn [& args]
(println log-statement)
(apply function-to-call args)))
This is the segment of code that has me confused. This is what I can decipher so far:
(defn with-log [function-to-call log-statement ] ..) is defining a function with name "with-log" that takes arguments 'function-to-call' and 'log-statement' and function-to-call is a function being passed as a parameter to this function.
The next section is confusing to me : (fn [& args] .... is an anonymous function being defined here ? Is the 'with-log' function returning a new function definition ?
(fn [& args]
(println log-statement)
(apply function-to-call args))
So by calling (with-log somefunc "my label") -- is it just returing a new anonymous function ? Or is it invoking the anonymous function ?
with-log will yield a function that, when called, will do exactly what function-to-call did except with the side-effect that log-statement will be printed to *out* just before function-to-call is evaluated using the arguments given to the anonymous function.
This is an example of the Decorator Pattern - extending the behaviour of an existing function by wrapping it in another function i.e. the anonymous function created by with-log using the (fn ...) form.
In order for the decorator function with-log to work with any conceivable function-to-call, the anonymous function's argument list is specified so that it can be called with number of arguments using (fn [& args] ...). When the anonymous function calls function-to-call it 'unwraps' the argument list with the function apply).
Ways to make use of with-log might be:
((with-log some-fn "Calling some-fn") arg1 arg2)
or
(defn my-fn [a b]
(+ a b))
(def my-fn-with-logging (with-log my-fn "Calling my-fn"))
(my-fn 1 2) ; evaluates to 3
(my-fn-with-logging 1 2) ; prints "Calling my-fn" and evaluates to 3
It is returning the anonymous function, and it is not being called.
For example, this would invoke the anonymous function with the given arguments:
((with-log some-fn "log statement") arg1 arg2)
This works because the function being returned is the first item in the list, which means it gets invoked just like any other function would.
Yes, you're right. (fn ..) is a form which creates anonymous function. This piece of code, given a function f and some value s will return a function, which, when called, will print s and then invoke f:
user=> (defn with-log [function-to-call log-statement ]
(fn [& args]
(println log-statement)
(apply function-to-call args)))
#'user/with-log
user=> (with-log + "String")
#<user$with_log$fn__1 user$with_log$fn__1#147264b1>
user=> ((with-log + "String") 1 2 3)
String
6
user=>
Note the line starting with #<user$.... This is internal identifier of the anonymous function that just has been created, that is, simple call to with-log returns a function. And then we apply the same function (it is same in terms of its behavior; it will be different object in fact, because each call to with-log creates new "instance" of the same function) to a number of arguments. "String" string gets printed and then REPL shows us a result of (+ 1 2 3).
Here you can learn more about it.

Nullpointer in clojure when running doseq with multiple expressions in the body

The following expression in clojure works great:
(doseq [x '(1 2 3 4)] (println x))
This one gives me a nullpointer:
(doseq [x '(1 2 3 4)] ((println x)(println "x")))
It produces the following output:
user=> (doseq [x '(1 2 3 4)] ((println x)(println "x")))
1
x
java.lang.NullPointerException (NO_SOURCE_FILE:0)
user=> (.printStackTrace *e)
java.lang.NullPointerException (NO_SOURCE_FILE:0)
at clojure.lang.Compiler.eval(Compiler.java:4639)
at clojure.core$eval__5182.invoke(core.clj:1966)
at clojure.main$repl__7283$read_eval_print__7295.invoke(main.clj:180)
at clojure.main$repl__7283.doInvoke(main.clj:197)
at clojure.lang.RestFn.invoke(RestFn.java:426)
at clojure.main$repl_opt__7329.invoke(main.clj:251)
at clojure.main$legacy_repl__7354.invoke(main.clj:292)
at clojure.lang.Var.invoke(Var.java:359)
at clojure.main.legacy_repl(main.java:27)
at clojure.lang.Repl.main(Repl.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at jline.ConsoleRunner.main(ConsoleRunner.java:69)
Caused by: java.lang.NullPointerException
at user$eval__266.invoke(NO_SOURCE_FILE:26)
at clojure.lang.Compiler.eval(Compiler.java:4623)
... 14 more
nil
Just adding an extra set of parentheses around the body of a doseq gives me that nullpointer.
What am I doing wrong?
Well, you already figured out the solution, so just a few hints to explain the behavior:
In Clojure (just like in Lisp, Scheme, etc) everything is an expression and an expression is either an atom or a list. With regard to lists, the Clojure manual says
Non-empty Lists are considered calls
to either special forms, macros, or
functions. A call has the form
(operator operands*).
In your example, the body ((println x) (println x)) is a list and the operator is itself an expression which Clojure has to evaluate to obtain the actual operator. That is, you're saying "evaluate the first expression and take its return value as a function to invoke upon the second expression". However, println returns, as you noticed, only nil. This leads to the NullPointerException if nil is interpreted as an operator.
Your code works with (do (println x) (println x)) because do is a special form which evaluates each expression in turn and returns the value of the last expression. Here do is the operator and the expressions with println ar the operands.
To understand the usefulness of this behavior, note that functions are first-class objects in Clojure, e.g., you could return a function as a result from another function. For instance, take the following code:
(doseq [x '(1 2 3 4)] ((if (x > 2)
(fn [x] (println (+ x 2)))
(fn [x] (println (* x 3)))) x))
Here, I am dynamically figuring out the operator to invoke upon the element in the sequence. First, the if-expression is evaluated. If x is larger than two, the if evalutes to the function that prints x + 2, else it evaluates to the function that prints x * 3. This function is than applied to the x of the sequence.
I see you've already realised the problem, however please note you don't need a do:
(doseq [x '(1 2 3 4)] (println x) (println "x"))
doseq is (as the name suggests) a do already :)