TransWikia.com

Assign value to the symbol returned by function

Mathematica Asked by Saeki Amae on December 21, 2020

Ok, so here is example code:

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p, k] = 0;
p

After that I get the message

Set::write: Tag If in If[True,p,k] is Protected.

And p is still 2 instead of 0.
How can I make the p equal to 0 in this case?

EDIT: My question is general – how to return the symbol from some function, not only If – and be able to change its value later (for example by Set)

EDIT #2: I know that with associations I can do that easily:

Clear[p, flag, k];
v = <||>;
v[p] = 2;
v[k] = 1;
flag = True;
v[If[flag, p, k]] = 0;
v[p]

I just wish I could the same just on symbols..

3 Answers

Here are two methods that are essentially the same.

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
Evaluate[If[flag, p =.; p, k =.; k]] = 0;
p  {* 0 *}

If you want to use a function, maybe this method:

Clear[func, p, flag, k];

func[flag_?BooleanQ, str1_String, str2_String] := If[flag,
  Clear[str1]; ToExpression[str1],
  Clear[str2]; ToExpression[str2]]

p = 2;
k = 1;
flag = True;
Evaluate[func[flag, "p", "k"]] = 0;
p  (* 0 *)

The salient points are (1) the symbol must be cleared or unset and (2) use Evaluate on the left side of the equals sign.

Answered by LouisB on December 21, 2020

Here is a fairly concise but still silly way to do it.

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
ToExpression[If[flag, "p", "k"] <> "=0"];
p
0

However, I would rather write

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p = 0, k = 0];
p

and, I believe, so would everybody else. it is the standard practice and is both more concise and efficient then any playing games to limit the code to one written Set expression.

Answered by m_goldberg on December 21, 2020

At first I wasn’t sure how to realize this, but upon seeing m_goldberg’s example with Set inside of If, it hit me:

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, Set[p,#], Set[k,#]]&[0];
p

And this, of course, returns 0 if flag = True and 2 if flag = False.

It might be easier to see it this way:

Clear[p, flag, k];
p = 2;
k = 1;
flag = True;
If[flag, p=#, k=#]&[0];
p

which also works like the above. You could streamline this a bit more & wrap it into a function, but I think this answers your question & gives it to you in a form that is loose enough for you to modify to your desires! Nothing fancy, just anonymous functions.

Answered by CA Trevillian on December 21, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP