(updated question) Question in short:

I have a data

x = 1

I have an expression

method:= (this=this+1; this)

I want to apply the method to data, by replacing this by x, and then evaluate method. So I want a function func such that

SetAttributes[func, Holdfirst];

will evaluate method with this replaced by x.

(original question)I have a data:

data = <|x->1, y->2|>;

and a method

changex[] := this[x] = 2;
changey[] := this[y] = 3;

I want to evaluate changex,changey with this replace by data. I want a function func such that

func[ changex[]; changey[] ]

so that I have

data == <| x -> 2, y -> 3 |>

(1) I tried:

SetAttributes[func, HoldFirst];
func[exp_]:= Block[{this}, this = data; exp; data = this];

this will lead to the correct result,func[changex[]; changey[]]; data == <| x -> 2, y -> 3 |> but it is not what I want. It copies the entire data to this (what I get is this=<|x->1,y->2|>), evaluate exp (get this[x]=2;this[y]=3), then copy entire this back to data. No real replacement happens during the evaluationg of exp.

(2) To prevent copying the entire data of data to this, I tried

SetAttributes[func, HoldFirst];
func[exp_]:= Block[{this, data}, this = data; exp;];

This time, I put data as a local variable of Block, so this is set to be the unevaluated symbol data. During the evaluation of exp, each symbol this will be replaced by the symbol data. If I run

func[changex[]; changey[]]

what I get is Block[{this, data}, data[x]=2; data[y]=3;]. Unfortunately, the symbol data is just a local variable whose downvalues are HoldPattern[data[x]]:>2, HoldPattern[data[y]]:>3. And outside Block, data is not affected.

  • $\begingroup$ This may be helpful: mathematica.stackexchange.com/q/17767/9490 $\endgroup$
    – Jason B.
    Aug 24 '18 at 23:24
  • $\begingroup$ The above link discussed the Hold attribute, which is related. In my trials, I set data as a local variable in Block to keep the unevaluated form, but it becomes a local variable, and I don't know how to access it from outside Block. $\endgroup$
    – Nathan
    Aug 25 '18 at 2:40

Maybe you're looking for AssociateTo:

data = <|x -> 1, y -> 2, z -> 3|>;

AssociateTo[data, <|x -> 2, y->3|>];

<|x -> 2, y -> 3, z -> 3|>


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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