0

(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];
func[method]

will evaluate method with this replaced by x.


(original question)I have a data:

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

and a method

Clear[this];
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.

Nathan
  • 1
  • 1
  • This may be helpful: https://mathematica.stackexchange.com/q/17767/9490 – Jason B. Aug 24 '18 at 23:24
  • 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. – Nathan Aug 25 '18 at 02:40

1 Answers1

1

Maybe you're looking for AssociateTo:

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

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

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

Carl Woll
  • 130,679
  • 6
  • 243
  • 355