What does "%&" mean in Clojure? - clojure

I solved the 58th 4clojure problem using recursion but then I looked at another persons solution and found this:
(fn [& fs] (reduce (fn [f g] #(f (apply g %&))) fs))
Which is more elegant than my solution. But I don't understand what %& means? (I do understand what % means but not when it's combined with &). Could anyone shed some light on this?

It means the "rest arguments", as per this source.
Arguments in the body are determined by the presence of argument
literals taking the form %, %n or %&. % is a synonym for %1, %n
designates the nth arg (1-based), and %& designates a rest arg.
Note that the & syntax is reminiscent of the & more arguments in function parameters (see here), but &% works inside an anonymous function shorthand.
Some code to compare anonymous functions and their anonymous function shorthand equivalent :
;; a fixed number of arguments (three in this case)
(#(println %1 %2 %3) 1 2 3)
((fn [a b c] (println a b c)) 1 2 3)
;; the result will be :
;;=>1 2 3
;;=>nil
;; a variable number of arguments (three or more in this case) :
((fn [a b c & more] (println a b c more)) 1 2 3 4 5)
(#(println %1 %2 %3 %&) 1 2 3 4 5)
;; the result will be :
;;=>1 2 3 (4 5)
;;=>nil
Note that the & more or %& syntax gives a list of the rest of the arguments.

Related

Evaluate Vector of Forms with Parameters

I've been working to figure out a was to evaluate collections of forms with arguments.
An example function:
(defn x
[a b c]
(+ a b c))
I would like to evaluate collections of the function x, where only some parameters are defined and others are passed in to end up with a list of the products of the evaluations of the x functions in the collection:
(defn y
[z]
(map #(eval %) [(x z 1 1) (x z 2 2) (x z 8 64)]))
The question is: how do I introduce z as a parameter to each of the functions in the collection when I map eval to each? Is this possible?
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
Is there a better way to accomplish this?
Thanks!
First, let's use some more explanatory names, simplify the definition of x, and not use eval:
(defn sum [& xs]
(apply + xs)) ;; could be inlined instead of a function
(defn sum-with [z]
(map (partial apply sum)
[[z 1 1]
[z 2 2]
[z 8 64]]))
(sum-with 3)
=> (5 7 75)
But I assume your real world problem is something more complex than summing numbers, so I'll assume your x function is doing something else and requires some positional arguments i.e. the order of arguments matters:
(defn transmogrify [this n1 n2 that]
(+ n1 n2 (* this that)))
(defn evaluate-sums [a b]
(map (partial apply transmogrify)
[[a 1 1 b]
[a 2 2 b]
[a 8 64 b]]))
(evaluate-sums 3 9)
=> (29 31 99)
So if I understand correctly, you can accomplish your goal just by applying sequences of arguments to your function. Or to be more explicit with args/not use apply, just use a more specific anonymous function with map:
(defn evaluate-sums [z]
(map (fn [[this n1 n2 that]]
(transmogrify this n1 n2 that))
[[z 1 1 99]
[z 2 2 360]
[z 8 64 -1]]))
I am trying to avoid typing them all out because I have many inputs (hundreds) that I want to pass to x where I only have a small set of the second and third parameters (five or so) that I care about.
If your "fixed" arguments are always the same arity, then you can use variadic arity for the rest of the arguments:
(defn sum [a b & cs]
(apply + a b cs))
(defn evaluate-sums [zs]
(map (fn [[a b & cs]]
(apply sum a b cs))
[[1 1 zs]
[2 2 zs]
[8 64 zs]]))
Where zs is a collection/sequence of your extra arguments.

Anonymous function in Clojure

Maybe this sounds ridiculous question, but it is for me still not exactly clear the difference between where the # of a anonymous function should come. For example in this example i filter the divisors of a positive number:
(filter #(zero? (mod 6 %)) (range 1 (inc 6))) ;;=> (1 2 3 6)
but putting the # right before the (mod 6 %) will cause an error. Is there a rule where in such a context my anonymous function begins, and why should the # come before (zero? ...?
This shows how the #(...) syntax is just a shorthand for (fn [x] ...):
(defn divides-6 [arg]
(zero? (mod 6 arg)))
(println (filter divides-6 (range 1 10))) ; normal function
(println (filter (fn [x] (zero? (mod 6 x))) (range 1 10))) ; anonymous function
(println (filter #(zero? (mod 6 %)) (range 1 10))) ; shorthand version
;=> (1 2 3 6)
;=> (1 2 3 6)
;=> (1 2 3 6)
Using defn is just shorthand for (def divides-6 (fn [x] ...)) (i.e. the def and fn parts are combined into defn to save a little typing). We don't need to define a global name divides-6 if we are only going to use the function once. We can just define the function inline right where it will be used. The #(...) syntax is just a shorthand version as the example shows.
Note that the full name of the form #(...) is the "anonymous function literal". You may also see it called the "function reader macro" or just the "function macro". The syntax (fn [x] ...) is called the "function special form".
Clojure's filter function takes one or two arguments; either way, the first argument must be a function. So there's no "rule" where the anonymous function is defined, as long as ultimately, the first argument to filter is a function.
However, in this case, zero? does not return a function, so (zero? #(mod 6 %)) would cause filter to throw an error. And, in fact, (zero? #(mod 6 %) doesn't make sense, either, because zero? does not take a function as an argument.
filter takes two parameters:
a predicate (a filter, which is a function), and
a collection
So, in a simple way:
(defn my-predicate [x]
(zero? (mod 6 x)))
(def my-collection
(range 1 (inc 6)))
(filter
my-filter
my-collection)
# is a clojure macro, or something that preprocess and reorganize code for you. We can see the result of a macro with macroexpand-1 :
(macroexpand-1 '#(zero? (mod 6 %)))
; (fn* [p1__4777#] (zero? (mod 6 p1__4777#)))
or in a more readable code:
(fn* [x]
(zero?
(mod 6 x))
On a single value of a collection, say 3, we can apply the above function:
( (fn* [x]
(zero?
(mod 6 x)))
3)
; true
And then back to the # version of our code, the input parameter of a function is implicitly %, so:
(
#(zero? (mod 6 %))
3)
; true
And finally, back to your original function, you see why # needs to be the function defining the predicate for the filter function:
(filter
#(zero? (mod 6 %))
(range 1 (inc 6)))
; (1 2 3 6)

What does %-mark mean in Clojure?

I've tried to find the answer but it's quite difficult to search just the %-mark. So I've seen %-mark sometimes but I can't understand what is its function. It would be very nice if somebody could tell the explanation.
I'm assuming this is inside an anonymous function, like #(first %) if so it means the first parameter. If there are more that one, you can number them %1,%2 etc.
So for instance
(filter #(odd? %) [1 2 3 4 5 6]) => (1 3 5)
Note: In this example you would normally just do (filter odd? [1 2 3 4 5 6])
#(blah %) is shorthand for an argument to an anonymous function. So if you're squaring each element in a list, instead of
(map (fn [x] (* x x)) [1 2 3])
you can write
(map #(* % %) [1 2 3])
i.e. substituting #(* % %) for (fn [x] (* x x)) as the anonymous function. Each will give (1 4 9)
% is just a placeholder for arguments in the #(...) reader macro witch rewrites to a (fn* ...) call. It means the first passed argument.
You can add a number after the % to indicate index number of argument, beware first argument index is 1, so % == %1.
You shall provide as many arguments to the returned function as the highest index you use in the function definition.
#(str %4 %2)
gives
(fn* [p1__680# p2__679# p3__681# p4__678#] (str p4__678# p2__679#))
and needs 4 arguments.
Observe that %4 and %2 are managed first and in reading order and non used arguments are created after by the macro filling the gaps.

What's the name of # and % in clojure?

What is the name of the construct in clojure that uses # at the begining of the expression a % in the middle? For example
#(fn [a b] (% b a))
I've tried searching the documentation for it but as both characters that define it aren't alphanumeric my search hasn't been too successful.
It is a reader macro for the anonymous function declaration. See http://clojure.org/reader for a comprehensive list of reader macros.
For instance, #(* 5 %) translates to (fn [x] (* 5 x)).
Your example translates in reading phase to (fn [op] (fn [a b] (op a b))) (op is my choice of placeholder there.)
It appears in (at least) two places:
Under Other Useful Functions and Macros (but that doesn't mention %1 %2 etc).
In the Reader (which parses the program) - # causes dispatch to a reader macro via a table lookup (you have to look carefully, but this does describe %1 etc)
In neither case does it have a useful name (actually, "Dispatch" could be the implied name - see second link). More generally "#" is called octothorp, amongst other things (here in Chile, "gato" (cat) for some unknown reason).
(And yes, %1 %2 are the first and second parameters, etc, while %& is "rest" - you can use just % for the first - see second link).
PS As everyone else has said, it's shorthand for a function. So (fn [a b] (+ a b)) is equivalent to #(+ %1 %2):
Clojure> (#(println % % %2) 1 2)
1 1 2
nil
Clojure> (#(apply println %&) 1 2 3)
1 2 3
nil
The #() construction is shorthand for the definition of an anonymous function. The % sign is used as shorthand for the arguments it takes.
% for the first argument. %integer for multiple arguments (ie %1 %2). %& for the rest (unused) arguments wrapped in a sequence.
=> (#(println % %2 %3 %&) 1 2 3 4 5)
1 2 3 (4 5)
You can see what function it creates by doing a macroexpand on it
#((\ %1 %2) * %2))
=> (macroexpand-1 '#((\ %1 %2) * %2))
(fn* [p1__744# p2__745#] ((\space p1__744# p2__745#) * p2__745#))
in normal words the following are the same:
#((\ %1 %2) * %2))
(fn [p1 p2] ((\ p1 p2) * p2))
Be careful to note that your example creates an anonymous function with a new anonymous function inside it.
"#" should be the lambda character, and % represents the first argument expected

How do I pass variables as variable names to a function?

I want to be able to do the following pseudocode:
Pass in symbol a.
Pass in symbol b.
Pass in an expression using a and b
As I change the value of a and b, print the output of c at each moment.
Ideally, I would like the signature to look like:
(runner a b (+ a b))
but I'm not sure that I'm approaching this correctly... I've tried changing the function to
(runner 'a 'b (+ 'a 'b))
and this more complicated example:
(runner 'a 'b (+ (* 'a 'b) 'a))
but this does a + on 'a and 'b before stepping into runner.
Here's my first stab at some clojure:
(defn runner [a b c] (
(for [i (range 10)
j (range 10)] (println i j (c i j))
What concept of clojure am I missing?
Function arguments are always evaluated before the function is called. If you want to defer evaluation or represent some computation or code as an object, you have a few options:
Use a function (see my code below)
Use a macro and splice some code into some other code that the macro generates
Pass code as a quoted list, and eval it.
Using a function is what you want to do 99% of the time. 1% of the time, you'll want macros. You should never need eval unless you're generating code at runtime or doing very screwy things.
user> (defn runner [f]
(doseq [a (range 3)
b (range 3)]
(println a b (f a b))))
#'user/runner
user> (runner (fn [x y] (+ x y)))
0 0 0
0 1 1
0 2 2
1 0 1
1 1 2
1 2 3
2 0 2
2 1 3
2 2 4
This could also be written as (runner #(+ %1 %2) or even simply (runner +).
There is no need to pass "a" and "b" into the function as arguments. doseq and for introduce their own local, lexically scoped names for things. There's no reason they should use a and b; any name will do. It's the same for fn. I used x and y here because it doesn't matter.
I could've used a and b in the fn body as well, but they would have been a different a and b than the ones the doseq sees. You may want to read up on scope if this doesn't make sense.
I would make its signature be something like
(runner alen blen op)
example:
(runner 10 10 +)
I'm not really sure i'm answering the correct question. I'm thinking "if i pass a function a symbol instead of a value how can it use the value that symbol represents? is that close?
(def a 4)
(defn my-inc [x] (+ (eval x) 1))
user> (my-inc 'a)
5
I'm sure there is a more elegant way than using eval.
It isn't clear enough to me what you're trying to achieve, but the following is an answer to what I guess is your question:
user=> (declare a b)
#'user/b
user=> (defn runner [] (+ a b))
#'user/runner
user=> (binding [a 1 b 2] (runner))
3
user=> (binding [a 2 b 3] (runner))
5
Note that the above style is likely not what you ought to be doing. Ask a better question and we'll give you better answers.