I want to define a symbolic-valued function using Set to memoize the result. However, I get different results when using an Association and a List:
f1[x_] = (Pause[3];{"a"->1,"b"->x}) f2[x_] := (Pause[3];{"a"->1,"b"->x}) g1[x_] = (Pause[3];Association@@{"a"->1,"b"->x}) g2[x_] := (Pause[3];Association@@{"a"->1,"b"->x}) When running these functions, only f1 and f2 produce the correct result, and only f1 memoizes the result, only requiring one computation involving a Pause (here standing in for a more expensive computation).
In[2]:= f1[y] Out[2]= {"a" -> 1, "b" -> y} In[3]:= f2[y] Out[3]= {"a" -> 1, "b" -> y} (* long computation *) In[4]:= g1[y] Out[4]= <|"a" -> 1, "b" -> x|> (* incorrect *) In[5]:= g1[y] Out[5]= <|"a" -> 1, "b" -> x|> (* incorrect; long computation *) Looking at the common pitfalls question, one finds that Associations were atomic in Mathematica™ 10.4. I am currently using version 13, and it appears that AtomQ@Association == True still. I suspect this is causing the issue I am working with.
As Mathematica™'s built-in dictionary data structure, I first attempted to use it to build a class-like object one can build easily in other languages. Building getters and setters with Associations is relatively easy, but now function definitions are getting complicated.
Am I better off using lists of rules to get around this issue, or is there a workaround I can use, perhaps with Replace[expr,x->#]& or something to that effect?
Setinstead ofSetDelayed- end of story. Useg2as you have written it, notg1. $\endgroup$g2[y]and not a repeat ofg1[y]. $\endgroup$