Bug with Block & Lookup: Scope Variable Leak

After debugging a large chunk of code, I could identify this MWE.

ClearAll@test
test[var_String]:= Block[{association},
association = <|"x"-> <|"key01"-> "ok"|>|>[var];
Lookup[association,"key01",{}]
]

If I evaluate:

test["x"]
test["y"]
test["x"]

I get an error evaluating the last test["x"]. What is very strange, I expected to find an error just in the evaluation of test["y"].

The same error does not occur if we change from Block to Module. In the Block case, we have some sort of unexpected scope leak. Is this a bug?

Tested in Mathematica version 11.3
Cross post in Mathematica Community

• Lookup has the attribute HoldAllComplete, which means it sees the symbol association, not its value. I don't think the bug is in Block. – Michael E2 Dec 8 '17 at 17:12
• @MichaelE2 I did a smaller toy code. But I don't understand why the memory. Why I get error when evaluation test["x"] by the second time. – Murta Dec 8 '17 at 17:15
• I don't know enough (or any) of the internals of Associations. It looks like Lookup is remembering something perhaps. Lookup being the newer thing, I suspect it over Block; but I don't know for sure. Hopefully someone who knows more can explain. -- I guess it's clear it's the combination of both, since using a global association doesn't suffer the same problem. – Michael E2 Dec 8 '17 at 17:20
• I would say that there is a bug in an internal caching mechanism in the implementation of Lookup. I note that if we evaluate Update[Lookup] to flush its hidden caches, then test["x"] starts working again. – WReach Dec 8 '17 at 17:48
• This doesn't happen for Module because running a second time creates a new instantiation of association. In[1]:= Table[Module[{x}, x], 2] Out[1]= {x$5672, x$5673}. – Chip Hurst Dec 8 '17 at 21:37

1 Answer

Looks like a bug to me as well. Just as Michael I would suspect that the problem is more with Lookup than Block or Associations in general. Here is a code example which seems to confirm that it is Lookup which does some caching and obviously doesn't take into account that the Blocked variables value has changed:

ClearAll@test
test[var_String] := Block[{association},
association = <|"x" -> <|"key01" -> "ok"|>|>[var];
Print[association@"key01"];
Lookup[association, "key01", {}]
]

Doing your tests with the above shows that directly access will give the correct result, while only the call to Lookup does not do what is to be expected. It also looks like this only happens when the shown error occurs, it does not happen if no error occurs. I would suggest you file a report to WRI.