1
$\begingroup$

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?

$\endgroup$
7
  • $\begingroup$ Errr ... why? (tmp[[1 ;; Length@#]] = #) &@{11, 22, 33} $\endgroup$ May 3, 2013 at 2:28
  • $\begingroup$ MapIndexed[(tmp[[#2]] = #1) &, {11, 22, 33}] $\endgroup$ May 3, 2013 at 2:35
  • $\begingroup$ @belisarius thank you belisarius. But I don't get it. What do you mean? $\endgroup$
    – matheorem
    May 3, 2013 at 2:57
  • $\begingroup$ You're trying to build functionality upon side-effects. Although it's possible, better don't do that. $\endgroup$ May 3, 2013 at 3:05
  • $\begingroup$ @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. $\endgroup$
    – matheorem
    May 3, 2013 at 3:09

1 Answer 1

3
$\begingroup$

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.

$\endgroup$
12
  • $\begingroup$ 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 ofBlock. 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. $\endgroup$
    – matheorem
    May 3, 2013 at 13:49
  • $\begingroup$ And I really don't understand func_[boost2[expr_, sym__], arg___] ^:= . Why there is a Blank after func? what does it mean? $\endgroup$
    – matheorem
    May 3, 2013 at 14:09
  • $\begingroup$ @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. $\endgroup$
    – Mr.Wizard
    May 3, 2013 at 14:44
  • $\begingroup$ @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. $\endgroup$
    – Mr.Wizard
    May 3, 2013 at 14:48
  • $\begingroup$ @matheorem I just noticed an error in my code above which I will correct now. I will also add another example. $\endgroup$
    – Mr.Wizard
    May 3, 2013 at 14:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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