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

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

Related

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.

In clojure, how to map a sequence and create a hash-map

In clojure, I would like to apply a function to all the elements of a sequence and return a map with the results where the keys are the elements of the sequence and the values are the elements of the mapped sequence.
I have written the following function function. But I am wondering why such a function is not part of clojure. Maybe it's not idiomatic?
(defn map-to-object[f lst]
(zipmap lst (map f lst)))
(map-to-object #(+ 2 %) [1 2 3]) => {1 3, 2 4, 3 5}
Your function is perfectly idiomatic.
For a fn to be part of core, I think it has to be useful to most people. What is part of the core language and what is not is quite debatable. Just think about the amount of StringUtils classes that you can find in Java.
My comments were going to get too long winded, so...
Nothing wrong with your code whatsoever.
You might also see (into {} (map (juxt identity f) coll))
One common reason for doing this is to cache the results of a function over some inputs.
There are other use-cases for what you have done, e.g. when a hash-map is specifically needed.
If and only if #3 happens to be your use case, then memoize does this for you.
If the function is f, and the resultant map is m then (f x) and (m x) have the same value in the domain. However, the values of (m x) have been precalculated, in other words, memoized.
Indeed memoize does exactly the same thing behind the scene, it just doesn't give direct access to the map. Here's a tiny modification to the source of memoize to see this.
(defn my-memoize
"Exactly the same as memoize but the cache memory atom must
be supplied as an argument."
[f mem]
(fn [& args]
(if-let [e (find #mem args)]
(val e)
(let [ret (apply f args)]
(swap! mem assoc args ret)
ret))))
Now, to demonstrate
(defn my-map-to-coll [f coll]
(let [m (atom {})
g (my-memoize f m)]
(doseq [x coll] (g x))
#m))
And, as in your example
(my-map-to-coll #(+ 2 %) [1 2 3])
;=> {(3) 5, (2) 4, (1) 3}
But note that the argument(s) are enclosed in a sequence as memoize handles multiple arity functions as well.

Clojure :: arity-overloaded functions calling each other

Examples of Clojure arity-overloading on functions like the following (taken from the cookbook):
(defn argcount
([] 0) ; Zero arguments
([x] 1) ; One argument
([ x & args] (inc (count args)))) ; List of arguments
... use a form that doesn't seem to allow the functions of lower arity to simply call the functions of higher arity with some default values (that's a common idiom in Java).
Is some other special form used for that ?
There's usually a good way to express the higher arity arguments in a way that doesn't need to refer to other arities using higher order functions and map / reduce. In this case it's pretty simple:
(defn argcount
([] 0)
([x] 1)
([x & args]
(reduce + 1 (map (constantly 1) args))))
Notice the general form of the expression is:
(reduce reducing-function arity-1-value (map mapping-function rest-of-args))
You can't do everything this way, but this works for a surprisingly large proportion of multi-argument functions. It also gains the advnatages of laziness using map, so you can do crazy things like pass ten million arguments to a function with little fear:
(apply argcount (take 10000000 (range)))
=> 10000000
Try that in most other languages and your stack will be toast :-)
mikera's answer is awesome; I'd just add an additional method.
When the a default value is needed for an overloaded function, a local can be used.
In the example division below, the local requires numbers and precision. The defined function overloads the precision with a default value.
(def overloaded-division
(let [divide-with-precision
(fn [divisor dividend precision]
(with-precision precision (/ (bigdec divisor) (bigdec dividend))))]
(fn
;lower-arity calls higher with a default precision.
([divisor dividend] (divide-with-precision divisor dividend 10))
;if precision is supplied it is used.
([divisor dividend precision] (divide-with-precision divisor dividend precision)))
)
)
When called at lower-arity, the default it applied:
user=> (overloaded-division 3 7)
0.4285714286M
user=> (overloaded-division 3 7 40)
0.4285714285714285714285714285714285714286M

Calling Clojure higher-order functions

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.

Higher-order functions in Clojure

Clojure is awesome, we all know this, but that's not the point. I'm wondering what the idiomatic way of creating and managing higher-order functions in a Haskell-like way is. In Clojure I can do the following:
(defn sum [a b] (+ a b))
But (sum 1) doesn't return a function: it causes an error. Of course, you can do something like this:
(defn sum
([a] (partial + a))
([a b] (+ a b)))
In this case:
user=> (sum 1)
#<core$partial$fn__3678 clojure.core$partial$fn__3678#1acaf0ed>
user=> ((sum 1) 2)
3
But it doesn't seem like the right way to proceed. Any ideas?
I'm not talking about implementing the sum function, I'm talking at a higher level of abstraction. Are there any idiomatic patterns to follow? Some macro? Is the best way defining a macro or are there alternative solutions?
Someone has already implememented this on the Clojure group. You can specify how many args a function has, and it will curry itself for you until it gets that many.
The reason this doesn't happen by default in Clojure is that we prefer variadic functions to auto-curried functions, I suppose.
I've played a bit with the functions suggested by amalloy. I don't like the explicit specification of the number of argument to curry on. So I've created my custom macro. This is the old way to specific an high order function:
(defn-decorated old-sum
[(curry* 3)]
[a b c]
(+ a b c))
This is my new macro:
(defmacro defn-ho
[fn-name & defn-stuff]
(let [number-of-args (count (first defn-stuff))]
`(defn-decorated ~fn-name [(curry* ~number-of-args)] ~#defn-stuff)))
And this is the new implicit way:
(defn-ho new-sum [a b c] (+ a b c))
As you can see there is no trace of (curry) and other stuff, just define your currified function as before.
Guys, what do you think? Ideas? Suggestions?
Bye!
Alfedo
Edit: I've modified the macro according the amalloy issue about docstring. This is the updated version:
(defmacro defhigh
"Like the original defn-decorated, but the number of argument to curry on
is implicit."
[fn-name & defn-stuff]
(let [[fst snd] (take 2 defn-stuff)
num-of-args (if (string? fst) (count snd) (count fst))]
`(defn-decorated ~fn-name [(curry* ~num-of-args)] ~#defn-stuff)))
I don't like the if statement inside the second binding. Any ideas about making it more succint?
This will allow you to do what you want:
(defn curry
([f len] (curry f len []))
([f len applied]
(fn [& more]
(let [args (concat applied (if (= 0 (count more)) [nil] more))]
(if (< (count args) len)
(curry f len args)
(apply f args))))))
Here's how to use it:
(def add (curry + 2)) ; read: curry plus to 2 positions
((add 10) 1) ; => 11
The conditional with the [nil] is meant to ensure that every application ensures some forward progress to the curried state. There's a long explanation behind it but I have found it useful. If you don't like this bit, you could set args as:
[args (concat applied more)]
Unlike JavaScript we have no way of knowing the arity of the passed function and so you must specify the length you expect. This makes a lot of sense in Clojure[Script] where a function may have multiple arities.