Pure function with attributes of arbitrary number of arguments: Is it possible?
Yes, this form exists, and was first shown to me by Leonid. It is:
Function[Null, (* body with ## *), (* attributes *)]
As always the Null
may be implicit, so in your application:
Function[, Length[Unevaluated@#1]{##2}, HoldFirst][1+2,2+3,3+1]
{10, 8}
This is the answer merged from this more recent question
The form in question
I meant the form
Function[Null, body-using-slots, attrs]
as ciao correctly noted.
At least at the time when I wrote the book, this form hasn't been documented. I learned about it from Roman Maeder's book "Programming in Mathematica". OTOH, this form is very useful in some cases, particularly with Hold
- attributes.
Use cases
I can think of two major classes of use cases for this form
Cases, when we could get away with using named arguments, such as
Function[{x,y}, x = y, HoldFirst]
but prefer not to, because of scoping problems / leaks associated with this form. Basically, the mentioned leak makes passing such functions into other functions generally unreliable. And it does happen in practice, I was bitten by this many times, most recently just a couple of weeks ago. This problem isn't there for
Slot
- based functions, although the latter have more limited nesting capabilities.Note, however, that in modern versions of Mathematica, a new system option
"StrictLexicalScoping"
is available, thanks to Daniel Lichtblau, which solves this problem. But, for certain reason, it is not yet a default, and if you write code for others, you probably can't count on it being set toTrue
on their machines, so having alternatives is still useful. This option has been discussed a few times here on SE.Cases, where we don't know the number of arguments in advance, and also where this number may not be fixed, but varies from call to call. Here is an example of such a function, written by Mr.Wizard in this answer: it computes the length of passed first argument, without evaluating it, and multiplies the list of rest of the arguments by it:
Function[Null, Length[Unevaluated@#1]{##2}, HoldFirst]
A few more examples
Here is another general example I found, from the question MapThread with non-rectangular lists, the solution given by Rojo:
Function[Null, f[##], Listable] @@ A
I also found a couple of my own posts containing this form: here I used it in this block of code:
MapThread[
Function[Null, Hold[#1 = #2], HoldAll],
Unevaluated @ {vars, vals}
]
which generates held assignments to variables without evaluation leaks, and here, where the following pattern
s_?(Function[Null, ListQ[Unevaluated[#]], HoldAll])
was used to test for an argument having the head List
, without evaluating it.
Summary
The form in question is
Function[Null, body-using-slots, attrs]
which is really useful in a number of circumstances. The use cases for it divide into two large categories:
Cases where
Function
with named arguments can be used in principle, but we still prefer the slot-based function. One of the main reasons for this is to avoid lexical scoping issues.Cases where
Function
with named arguments can not be used even in principle, simply because the number of arguments is unknown at function's construction time, or can vary from call to call.