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.

question is as follows

define a list

ttt={1,2};

and if I set values in this way

{ttt[[1]],ttt[[2]]}={3,4}

then the value of list ttt now becomes {3,4}

Now I try this

f:={ttt[[1]],ttt[[2]]}

then ?f will show that f:={tmp[[1]],tmp[[2]]}

then if I just write

f={3,4}

this will not affect the values of list ttt .

the question is that I want the values of list ttt changes as well when I set values to f. How to do this?


More Question!!

why the following code didn't change the value of ttt??

Table[With[{i = i}, Defer@ttt[[i]]], {i, 1, 2}] = {111, 222}

while

Table[With[{i = i}, Defer@ttt[[i]]], {i, 1, 2}]

really gives

{ttt[[1]],ttt[[2]]}
share|improve this question
    
The assignment to list part (ttt[[3]]=val) only works, if the list part is at the left hand side of the Set operator (as Set has attribute HoldFirst), otherwise it simply returns the appropriate element of ttt. –  István Zachar May 2 '13 at 8:59
    
You can make ttt change when f changes by using SetDelayed, as in ttt:=f. But it sounds like you are trying to do this at the same time as you set f:=ttt. You can't do both at once because it creates a circle (you will get a recursion error). –  bill s May 2 '13 at 9:31

2 Answers 2

up vote 3 down vote accepted

I would approach this by combining the functionality of bump given in:
Elegant manipulation of the variables list
with my step evaluation function described here:
How do I evaluate only one step of an expression?

The step function is needed to (easily) recover the expression {ttt[[1]], ttt[[2]]} from the definition of f without it fully evaluating. It can be used like this, with the injector pattern:

ttt = {1, 2};
f := {ttt[[1]], ttt[[2]]}

step[f] /. _[x_] :> (x = {3, 4})

ttt
{3, 4}

To make this more convenient, and to work with other functions (see the first question linked above for examples) I would then write (after loading step):

func_[boost[expr_], arg___] ^:= step[expr] /. _[x_] :> func[x, arg]

Example of use:

boost[f] = {5, 6};

ttt
{5, 6}
share|improve this answer
    
This is very cool. +1 –  Simon Woods May 3 '13 at 8:13
    
@Simon Thank you. :-) I have yet to find as nice a way to approach something like this as to use step; I find a lot of use for that function since writing it. Out of curiosity, are you using it for anything? –  Mr.Wizard May 3 '13 at 13:51
    
No, but I will in future! I must have seen it before, as I'd already upvoted the question and answer, but I'd forgotten about it. Stupid memory... –  Simon Woods May 3 '13 at 15:19
    
@Simon How I feel about my own memory: youtube.com/watch?v=ClgLvztrXbk –  Mr.Wizard May 3 '13 at 15:36

You may use ReleaseHold[Hold[f = {3, 4}] /. OwnValues[f]] :

ttt = {1, 2};
f := {ttt[[1]], ttt[[2]]};

ReleaseHold[Hold[f = {3, 4}] /. OwnValues[f]]

?ttt

(* ttt -> {3,4} *)

Some explanations :

  • The fullform of f={3,4} is Set[f, List[3, 4]].
  • Set has attribute Holdfirst.
  • We want to transform Set[f, List[3, 4]] in {ttt[[1]], ttt[[2]]}={3,4}.

So :
-f must be evaluated, that is to say f must become {ttt[[1]], ttt[[2]]}
- but {ttt[[1]], ttt[[2]]} must not be further evaluated to {1,2}.

The idea is to manually control the evaluation process with Holdand ReleaseHold. I use too the fact that /. x->y is effective inside a Hold.

Otherwise, OwnValues[f] gives the internal rule attached to f (with Down Values,UpValues...). The rule attached to ttt are not used.

To see what's happening, one can use ReleaseHold[Hold[f = {3, 4}] /. OwnValues[f]] // Trace // Column. It is not too much verbose.

NB : The fact that Set has attribute HoldFirst seems a little bit contradictory with the fact that {ttt[[1]],ttt[[2]]}={3,4} works. I have used a partially "try and see what's happening" approach to find the solution.

share|improve this answer
    
Thank you very much! Can I ask another question? Why this code doesn't work? Table[With[{i = i}, HoldForm@ttt[[i]]], {i, 1, 2}] = {111, 222} –  matheorem May 2 '13 at 14:25
    
There are several reasons. The main one is that when you write Table[...]]=... , Table[... is not evaluated (because it's the fist argument of Set), that is to says it simply stays inert. Set[...] treats most expressions like this. Lists (as in {x,y}=...) are exceptions (x and y are "extracted" from the expression {x,y}). I think a general rule of thumb is to autorise only lists and symbols to be on the left side of a =. –  andre May 2 '13 at 18:16
1  
a little comment : Stack Exchange is not a chat. One Question at a time. –  andre May 2 '13 at 18:37
    
Thank you andre! So there is no way to set values to Table directly? I really need to do it this way, because I have defined a function which is a table, with different argument, the table will be different. And I want to set values to the table list in the program. –  matheorem May 3 '13 at 0:10

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.