Have I found a big difference between using the short form and the long form of a pure function?

By referring to the Mathematica documentation, I learned to use ##2 to represent all the arguments but the first one. This is a brief way to represent a pattern matching all arguments but the first one. However, how can I do the same thing in the long Function[args. body] form?

For example, {##2}& @@ f[x1, x2, x3, x4] will give {x2, x3, x4}. Unfortunately, Function[{u1, u2}, {u2}] @@ f[x1, x2, x3, x4] only gives {x2}.

I think this occurs because the long form does not interally contain pattern matching functionality, although I find this hard to believe. So my question is whether the long form really ignores the functionality of pattern matching?

In general, are these two pure function forms identical in every aspect? That is, is the short form is just a shortcut for the long form?

• Function[{u1,u2}, {u2}] is equivalent to {#2} &, yes. I don't know of any "named argument" equivalent of SlotSequence[]. Commented Jun 22, 2013 at 3:34
• "Identical in every aspect" — No, because with the Function form, you can set attributes for pure functions when defining them (using the 3rd argument). BTW, only & is Function. #n is just Slot, denoting the nth argument (and ##n is SlotSequence for nth argument onwards), so you can actually do Function[, {##2}]@{x1, x2, x3, x4}
– rm -rf
Commented Jun 22, 2013 at 4:06
• @rm-rf Thanks! Function [x, {##2 & @@ x}]@f[x1, x2, x3, x4] works, although the key to give expected result is due to ##2 & again. BTW, can I reproduce the result by only applying the Function[] form? Commented Jun 22, 2013 at 4:18
• To drive home the fact that & is the shorthand form of Function[], ponder on the result of FullForm[{#} &], among other things. Commented Jun 22, 2013 at 4:40
• You should also ponder on FullForm[{##2} &]. Commented Jun 22, 2013 at 11:45

I seem to recall an earlier question addressing this specific aspect (is there a ## equivalent for named parameters) but I cannot find it. Nevertheless...

I echo Leonid's answer that there are important differences between pure functions using Slot and/or SlotSequence and named parameters. A primary one is the automatic renaming that occurs with the latter; see: Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs.

A simple illustration is creating a function that creates a Function:

f1 = Function[stuff, Function[{x}, stuff]][x^2]

f2 = Function[stuff, stuff &][#^2]

Function[{x$}, x^2] #1^2 &  Notice that f1 is broken because x has been silently replaced with x$ -- this can be desirable behavior but it can also prevent exactly what you intend as is the case here.

As noted in comments the internal form of & is actually Function, though it is usually not entered that way when using # or ##:

Head[{#, ##2} &]

FullForm[{#, ##2} &]

Function

Function[List[Slot[1],SlotSequence[2]]]


There is an undocumented syntax for Function: if the first argument is Null you can use the third parameter (attributes) along with Slot:

Function[Null, Hold[##], HoldAll][2 + 2, Sqrt[4]]

Hold[2 + 2, Sqrt[4]]


Null may of course be entered implicitly, e.g.:

Function[, ff @ ##2][1, 2, 3, 4]

ff[2, 3, 4]

• [email protected]. I wonder how can these undocumented syntax be learned. I am a noob learning from Leonid's note and the built-in documentation. This is the knowledge that I can learn so far. BTW, SE is a good university for learning. Commented Jun 23, 2013 at 2:26
• @Life You're welcome. I learned this particular syntax from Leonid here on StackExchange (StackOverflow, more specifically). This site is the best resource I have found but if you have the interest there are many other sources as well; a huge list is compiled here. Also, while I find this site easier to participate in the MathGroup Archive is still an excellent resource that should not be overlooked. Commented Jun 23, 2013 at 3:13
• Thanks again! StackOverflow seems to be a melting pot for Computer-Language-based problems. Commented Jun 23, 2013 at 6:11
• And impressed by Evaluate[ ]. It totally destroys the sequence of rules transformation held by HoldAll attributes. Simply regard the output form of Evaluate[ ] as Head's argument. Commented Jun 23, 2013 at 6:15

FWIW, I disagree with the answers which state that Function with named arguments and Function expressed using slots (#) are the same thing. Please see the first part of this answer of mine for a partial list of differences.

The main difference I want to stress here is that Function-s with named arguments are true (albeit leaky) lexical scoping constructs, while Functions using slots are not quite (which is why, in particular, they can not be non-trivially nested).

Other technical differences such as support for arbitrary number of arguments for slot-based functions and its lack for functions with named arguments, etc. were mentioned in other answers.

• Thanks! I also noticed # and & form cannot be easily nested without applying the functionality from With. In the example you mentioned<stackoverflow.com/questions/4920194/using-nested-slots>, I hope With[{x = #1}, Array[#1^#2 == x &, {x, x}]] & will be an answer. Commented Jun 22, 2013 at 16:51

Just to get an answer on record, the answer to your question is "no".

The correct long form of {##2} & @@ f[x1, x2, x3, x4] is Function[{SlotSequence[2]}] @@ f[x1, x2, x3, x4]. Both give {x2, x3, x4}.