8
$\begingroup$

I've always thought

(2#+1)&

and

Function[x,2x+1]

are interchangeable in common sense. But,

Clear[F]; F[x_] := (2 # + 1) &[x^2]; F[3]
(* 19 *)

Clear[F]; F[a_] := Function[x, 2 x + 1][a^2]; F[3]
(* 19 *)

Clear[F]; F[x_] := Function[x, 2 x + 1][x^2]; F[3]
(* Function::flpar: Parameter specification 3 in Function[3,2 3+1] should be a symbol or a list of symbols. *)
(* Function::flpar: Parameter specification 3 in Function[3,2 3+1] should be a symbol or a list of symbols. *)
(* Function[3, 2 3 + 1][9] *)

As you see, it seems mathematica provokes an error if you use same variable used in Function[ ], to define a new function.

Looks mathematica wants to prevent a kind of collision of variable names. But I think such thoughtfulness is unnecessary for this case. Function[x, 2 x + 1] just represents a function that maps a thing to its double plus one. After completing interpretation of the function, we can completely forget the fact : 'the variable used in Function[ ] was x'. What do you think ?

$\endgroup$
2
  • 2
    $\begingroup$ The main problem is that you are using a delayed assignment :=, which redefines the anonymous function every time you call F. The problem probably goes away by using an immediate assignment =. Here's a tutorial. $\endgroup$
    – Roman
    Jun 27 at 12:36
  • 3
    $\begingroup$ Similar: How to prevent name clash between arguments of different functions?. Using named arguments with Function comes with risks that are usually easily avoided by sticking with slot notation. $\endgroup$
    – WReach
    Jun 27 at 17:51
14
$\begingroup$

The issue is that to SetDelayed1 (:=), Function is just a normal head. For your third example, this means the following: You are defining a downvalue for F that says "every time you see F[something] replace it with the expression Function[x, 2 x + 1][x^2], where all x are to be replaced by something". Notice that at no point in that process is the head Function treated separately. This means that the x inside Function is simply replaced by 3 in your example before Function has any change to do anything.

Now, there are some functions that do treat Function differently, e.g. With:

With[{x = 1}, Function[x, x]]
(* Function[x, x] *)

That being said, I do think that your initial statement is pretty much correct: Function[x,2x+1] and 2#+1& are mostly identical, the only issue is that SetDelayed1 knows about neither of them, and will blindly replace parts inside them. You could equally well break the second version:

Clear[F]; F[Slot_] := (2 # + 1) &[Slot^2]; F[3]
(* 1 + 2 3[1] *)

The only difference here is that there is no error message, and since # is Slot[1] (and not Slot), the failure mode is slightly different, but the point still stands I think.

1 As noted by Leonid Shifrin in the comments, it is not really accurate to say that the behavior described here is due to SetDelayed. SetDelayed effectively defines replacement rules (with head RuleDelayed), that are then applied using a mechanism similar to Replace. This means that it would be more accurate to say that the rule application mechanism of Mathematica does not know or care about Function.

$\endgroup$
3
  • $\begingroup$ The first sentence is so impressive "The issue is that to SetDelayed (:=), Function is just a normal head. " Thank you. $\endgroup$
    – imida k
    Jun 28 at 2:26
  • 1
    $\begingroup$ I would mostly agree with this answer, except I think that the significance of SetDelayed here is overemphasized: rather, the main culprit is RuleDelayed and rule application in general, while SetDelayed simply creates a rule. This is just another manifestation of the well-known fact that rule application does not generally respect inner scoping constructs, not even other delayed rules. Similar problems were discussed in 1 (see at the end of that post) and 2. $\endgroup$ Jun 28 at 5:52
  • 1
    $\begingroup$ @LeonidShifrin Thanks, that's a very good point! I have added a note to the answer to hopefully clear things up a bit $\endgroup$
    – Lukas Lang
    Jun 28 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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