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.

I want to create a function that will take a variable $x$ and reassign the value $x+2$ to $x$.

So

f[x_]:= x += 2

However:

f[10]

yields the Mathematica error

AddTo::rvalue: 10 is not a variable with a value, so its value cannot be changed.

Which makes sense, as I am asking Mathematica to assign the value of 12 to 10. So how can I do this so that it changes the assigned value of some variable $x$?

share|improve this question
    
Because I want to assign the new value of x+2 to x, for further use. –  Kieran Cooney Jun 26 at 21:24
    
I realize that now, but that's not what your first sentence says. It says "I want to create a function that will take a variable x and return x+2.", not "I want to create a function that will take a variable and re-assign its value." Could you clarify the post a bit? –  Szabolcs Jun 26 at 21:25
    
You're right; thanks for your correction. –  Kieran Cooney Jun 26 at 21:27

2 Answers 2

up vote 5 down vote accepted

You can set f to hold its arguments, like so:

ClearAll[f];
SetAttributes[f, HoldAll]
f[x_] := x += 2

Then

x = 5
f[x]
x

evaluates to

(*
5
7
7
*)

You can also use the third argument of Function for this, like so:

f = Function[{z}, z += 2, HoldAll]
share|improve this answer

Let's pretend that f is going to be a function that will see serious use. For such functions, we must consider not only normal use cases, but also edge cases and outright abuse. And we must also consider how f will act in combination with other functions.

For this particular case, we might reason that f that, while f[5] may be of little value at top level, it makes sense for 1 + f[5] to evaluate to 8. Further, we might want to handle the edge case where x is value-free in the same way we would handle f[5]; e.g. return 2 + x. And finally we would want to print out a normal looking Mathematica style error message for abusive use such as f[] and f["string"].

ClearAll[f, x, y]
f::badarg = "f requires a symbol with a value or numeric value for its argument";
SetAttributes[f, HoldFirst]
f[x_Symbol] /; ValueQ[x] := x += 2
f[x : (_Symbol | _? NumericQ)] := x + 2
f[args : ___] := (Message[f::badarg]; Defer[f[args]])

Unit tests

Normal cases

x = 40; {f[x], x}
{42, 42}
{f[5], f[1 + Sqrt[2]], f[π]}
{7, 3 + Sqrt[2], 2 + π}

Edge case (y has no assigned value)

f[y]
2 + y

Abuse

{f["string"], f[{1, 2, 3}]}

f::badarg: f requires a symbol with a value or numeric value for its argument
f::badarg: f requires a symbol with a value or numeric value for its argument

{f["string"], f[{1, 2, 3}]}
share|improve this answer
    
complete treatment –  acl Jun 27 at 0:06

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.