In recent thread was raised the question: why anonymous pure functions Function[body]
(or body &
) do not rename symbols in nested scoping constructs while pure functions with named parameters Function[{vars}, body]
do rename them as seen from the following example:
lhs_ :> # &@arg
Function[rhs, lhs_ :> rhs]@arg
lhs_ :> arg
lhs$_ :> arg
(in the second case lhs
is renamed to lhs$
).
The provided explanation (first given in the comment) states that pure function with no named arguments isn't a scoping construct, hence localization of variables in the nested scope isn't performed. This looks as kind of obvious since there is no need to localize variables inside of a construct which doesn't use variables itself (anonymous pure functions use only Slot
).
But when trying to find where it is stated in the official Documentation, I was confused: the modern Documentation seems to state the opposite (although all the linked examples are only about the form Function[{vars}, body]
), emphasis is mine:
Function
constructs can be nested in any way. Each is treated as a scoping construct, with named inner variables being renamed if necessary. »
At the same time Leonid Shifrin notes in his book "Mathematica programming: an advanced introduction" (emphasis is mine):
It is important to note that there is no fundamental difference between functions defined with the
#
-&
notation and functions defined with theFunction
command, in the sense that both definitions produce pure functions. There are however several technical differences that need to be mentioned.The first one is that the
Function[{vars},body]
is a scoping construct, similar toModule
,Block
,With
etc.
what implies that only the form Function[{vars},body]
is a scoping construct, not the form defined with the #
- &
notation.
Let us make the things clear: is the form Function[body]
(and equivalent forms body &
and Function[Null, body]
) a scoping construct or not? I ask both for authoritative references and for rational analysis of the situation.
Comments
Post a Comment