Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
1  
Function[{u1,u2}, {u2}] is equivalent to {#2} &, yes. I don't know of any "named argument" equivalent of SlotSequence[]. –  J. M. Jun 22 '13 at 3:34
1  
"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 Jun 22 '13 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? –  Life Jun 22 '13 at 4:18
3  
To drive home the fact that & is the shorthand form of Function[], ponder on the result of FullForm[{#} &], among other things. –  J. M. Jun 22 '13 at 4:40
1  
You should also ponder on FullForm[{##2} &]. –  m_goldberg Jun 22 '13 at 11:45
show 2 more comments

3 Answers

up vote 6 down vote accepted

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]
share|improve this answer
    
Thanks@Mr.Wizard. 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. –  Life Jun 23 '13 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. –  Mr.Wizard Jun 23 '13 at 3:13
    
Thanks again! StackOverflow seems to be a melting pot for Computer-Language-based problems. –  Life Jun 23 '13 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. –  Life Jun 23 '13 at 6:15
add comment

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.

share|improve this answer
    
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. –  Life Jun 22 '13 at 16:51
add comment

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}.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.