# Pure function with attributes of arbitrary number of arguments: Is it possible?

Mathematica allows to define pure function, like

Function[{a, b},Length[Unevaluated@a]{b}][1+2,2+3]
(*
==> {0}
*)


Pure functions in Mathematica can take an arbitrary number of arguments, but only if not naming them, for example:

Function[Length[Unevaluated@#1]{##2}][1+2,2+3,3+1]
(*
==> {0,0}
*)


Also, pure functions can optionally have attributes, for example:

Function[{a,b},Length[Unevaluated@a]{b},{HoldFirst}][1+2,2+3]
(*
==> {10}
*)


However what I haven't found is a way to have both arbitrary many arguments and attributes:

Function[(* what, if anything, to put here? *)][1+2,2+3,3+1]
(*
==> {10, 8}
*)


Therefore my question:

Is it possible to define pure functions which take an arbitrary number of arguments and at the same time have attributes? And if so, how would one define them?

The obvious solution doesn't work:

Function[Length[Unevaluated@#1]{##2},{HoldFirst}][1+2,2+3,3+1]
(*
Function::flpar: Parameter specification Length[Unevaluated[#1]] {##2} in
Function[Length[Unevaluated[#1]] {##2},{HoldFirst}] should be a symbol or
a list of symbols. >>
*)


Adding an empty parameter list disables parameter substitution for ##;

Function[{},Length[Unevaluated@#1]{##2},{HoldFirst}][1+2,2+3,3+1]
(*
==> {##2}
*)


Of course, a workaround is easy; for example, have the pure function take a list (which in the example above would actually have been the better alternative anyway), or simply using a named function. So it's more of a curiosity. It just seems odd to have two completely orthogonal features of pure functions, and yet not being able to combine them.

-
You could do something like Function[, ##, <Attributes>], for instance. Is that what you were asking? –  rm -rf Jul 25 '13 at 17:25
@rm-rf: Yes. It's the first time I see an actual use for empty arguments; up to now I've only seen them as potential error source (due to an accidental extra comma). –  celtschk Jul 25 '13 at 17:31

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}

-
+1. To be pedantic, I will add that this form is undocumented (but very unlikely to be discontinued). –  Leonid Shifrin Jul 25 '13 at 18:02