Anonymous abbreviated function

Something I don’t understand about anonymous functions using short notation # (..)

The following works:

REPL> ((fn [s] s) "Eh") "Eh" 

But this is not so:

 REPL> (#(%) "Eh") 

It works:

 REPL> (#(str %) "Eh") "Eh" 

I do not understand why (# (%) "Eh") does not work, and at the same time I do not need to use str in ((fn [s] s) "Eh")

They are both anonymous functions, and both of them take one parameter here. Why does abbreviated notation need a function and another not?

+76
function anonymous-function clojure
Nov 03 '12 at 1:00
source share
3 answers
 #(...) 

is short for

 (fn [arg1 arg2 ...] (...)) 

(where the amount of argN depends on how much% N you have in the body). Therefore, when you write:

 #(%) 

he translated into:

 (fn [arg1] (arg1)) 

Note that this is different from your first anonymous function, which is similar:

 (fn [arg1] arg1) 

Your version returns arg1 as a value, the version that comes from the shorthand extension tries to call it a function. You get an error because the string is not a valid function.

Since shorthand provides a set of parentheses around the body, it can only be used to make one function call or special form.

+115
Nov 03
source share

As already mentioned in other answers, you sent #(%) to something like (fn [arg1] (arg1)) , which does not match (fn [arg1] arg1) .

@John Flatness pointed out that you can just use identity , but if you are looking for a way to write identity using the send macro #(...) , you can do it like this:

 #(-> %) 

By combining the send macro #(...) with the -> macro, it expands to the value (fn [arg1] (-> arg1)) , which again expands to (fn [arg1] arg1) , which you just need. I also found the macro -> and #(...) , useful for writing simple functions that return vectors, for example:

 #(-> [%2 %1]) 
+54
Nov 03 '12 at 5:30
source share

When you use #(...) , you can imagine what you write (fn [args] (...)) , including the brackets that you started immediately after the pound.

So your non-working example is converted to:

 ((fn [s] (s)) "Eh") 

which obviously does not work because you are trying to call the string "Eh". Your example with str works, because now your function is (str s) instead of (s) . (identity s) will be a closer analogue to your first example, since it will not force str.

This makes sense if you think about it, because besides this absolutely minimal example, every anonymous function is going to call something, so it would be foolish to require another set of partners to actually call.

+18
Nov 03
source share



All Articles