Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous function shorthand

There's something I don't understand about anonymous functions using the short notation #(..)

The following works:

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

But this doesn't:

REPL>  (#(%) "Eh") 

This works:

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

What I don't understand is why (#(%) "Eh") doesn't work and at the same time I don't need to use str in ((fn [s] s) "Eh")

They're both anonymous functions and they both take, here, one parameter. Why does the shorthand notation need a function while the other notation doesn't?

like image 210
Cedric Martin Avatar asked Nov 03 '12 01:11

Cedric Martin


People also ask

How do you write an anonymous function?

Anonymous Function is a function that does not have any name associated with it. Normally we use the function keyword before the function name to define a function in JavaScript, however, in anonymous functions in JavaScript, we use only the function keyword without the function name.

What do you mean by anonymous function?

In Python, an anonymous function is a function that is defined without a name. While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword. Hence, anonymous functions are also called lambda functions.

What does () => mean in JavaScript?

It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.

What is anonymous function in JavaScript?

In JavaScript, an anonymous function is that type of function that has no name or we can say which is without any name. When we create an anonymous function, it is declared without any identifier. It is the difference between a normal function and an anonymous function.


2 Answers

#(...) 

is shorthand for

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

(where the number of argN depends on how many %N you have in the body). So when you write:

#(%) 

it's translated to:

(fn [arg1] (arg1)) 

Notice that this is different from your first anonymous function, which is like:

(fn [arg1] arg1) 

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

Since the shorthand supplies a set of parentheses around the body, it can only be used to execute a single function call or special form.

like image 110
Barmar Avatar answered Sep 17 '22 08:09

Barmar


As the other answers have already very nicely pointed out, the #(%) you posted actually expands to something like (fn [arg1] (arg1)), which is not at all the same as (fn [arg1] arg1).

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

#(-> %) 

By combining the #(...) dispatch macro with the -> threading macro it gets expanded to something like (fn [arg1] (-> arg1)), which expands again to (fn [arg1] arg1), which is just want you wanted. I also find the -> and #(...) macro combo helpful for writing simple functions that return vectors, e.g.:

#(-> [%2 %1]) 
like image 35
DaoWen Avatar answered Sep 21 '22 08:09

DaoWen