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 have already asked a related question here why set values in this way doesn't work? But I think I have to write the question which I encountered explicitly?

tmp = {1, 2, 3, 4, 5}
label[i_, p_] := i + p
test[p_] := Table[tmp[[label[i, p]]], {i, 1, 2}]

Here I defined a function test and the thing I want to is that change the values of list tmp via setting values to function test. While simply write

test[1]={111,222}

and expecting tmp will change to {1,111,222,3,4,5} is not possible.

So how to achive this? I have tried many Hold things, but failed.

Inspired by andre. I know that Set has attribute HoldFirst. So I tried Evaluate

 Evaluate[test[1]]={111,222}

this won't work! I guess the problem is that I must properly Hold label[i,p] and tmp[[]] in the table. But I can't work it out. Anyone help?

share|improve this question
    
Errr ... why? (tmp[[1 ;; Length@#]] = #) &@{11, 22, 33} –  belisarius May 3 '13 at 2:28
    
MapIndexed[(tmp[[#2]] = #1) &, {11, 22, 33}] –  belisarius May 3 '13 at 2:35
    
@belisarius thank you belisarius. But I don't get it. What do you mean? –  matheorem May 3 '13 at 2:57
    
You're trying to build functionality upon side-effects. Although it's possible, better don't do that. –  belisarius May 3 '13 at 3:05
    
@belisarius thank you. So can you offer me a better way to achive my purpose? Or you said it's possible. I want to know how it is possible. –  matheorem May 3 '13 at 3:09
show 2 more comments

1 Answer 1

up vote 3 down vote accepted

This seems rather convoluted, and there is almost certainly an easier way to approach whatever it is you are wishing to do, but I like answering questions like this as it allows working with more unusual aspects of the language.

We can do this:

Block[{tmp, Part}, Hold @@ {test[2]}] /. _[x_] :> (x = {111, 222});

As with my previous answer we may wish to wrap this into a more convenient syntax, but there is a problem; how do we know that tmp is the symbol to be blocked? We can give it explicitly, if that is acceptable.

func_[boost2[expr_, sym__], arg___] ^:= 
  Block[{sym, Part}, Hold @@ {expr}] /. _[x_] :> func[x, arg]

Use syntax:

boost2[test[1], tmp] = {111, 222};

I'm not certain if there is any point in keeping the generalized form of this function in analogy to the original bump function, but it was easy for me to write it this way. If you wish only to have this operation apply to Set it may be simpler to write a mySet analog, like this:

SetAttributes[mySet, {HoldAll, SequenceHold}]

mySet[expr_, sym__, value_] := 
  Block[{sym}, Hold @@ {expr} // Quiet] /. _[x_] :> (x = value)

mySet[test[1], tmp, {111, 222}]

To me this syntax is not as elegant as the form above.

share|improve this answer
    
Thank you Mr.Wizard. Sorry for the late comment. I spent 10 hours reading mathematica docs and doing experiment on mathematica.In the end, I still can't make all that clear. I am really frustrated with my IQ. So here is the question, I think I don't have a good understanding of`Block`. For example, Why x=7;Block[{x},Print[x]] gives x not 7?? why Block[{tmp},Hold@@{tmp[[1]]}]gives Hold[tmp[[1]]], while Hold@@[tmp[[1]]] gives 1 ?? And why your code include Part in the Block list. I tried remove the Part, though it will give error message, but the tmpreally changes. –  matheorem May 3 '13 at 13:49
    
And I really don't understand func_[boost2[expr_, sym__], arg___] ^:= . Why there is a Blank after func? what does it mean? –  matheorem May 3 '13 at 14:09
    
@matheorem You should read this; I particularly like WReach's answer as it succinctly summarizes the behavior of these functions. The reason I Block tmp and Part is to prevent either of them from evaluating inside the Block[ . . . ] allowing me to easily manipulate the expression without it evaluating all the way. –  Mr.Wizard May 3 '13 at 14:44
    
@matheorem the definition func_[boost2[expr_, sym__], arg___] ^:= is more complicated than it may need to be for your application. It is an UpSetDelayed definition that will attach an UpValue to boost2. The pattern func_ will match any head (function) with arguments of the form boost2[expr_, sym__], arg___. Please review this documentation page. –  Mr.Wizard May 3 '13 at 14:48
    
@matheorem I just noticed an error in my code above which I will correct now. I will also add another example. –  Mr.Wizard May 3 '13 at 14:51
show 7 more comments

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.