For cases where one has already assigned DownValues associated with the name ‘a’, is there an accepted way to block the assignment of OwnValues to the same name? (I originally came across this issue while playing with someone’s attempt at implementing a data dictionary.)
Here’s what I mean to avoid:
Remove[a];
a[1] := somethingDelayed
a[2] = somethingImmediate;
DownValues[a]
a[1]
a[2]
Returns…
{HoldPattern[a[1]] :> somethingDelayed,
HoldPattern[a[2]] :> somethingImmediate}
somethingDelayed
somethingImmediate
And now if we were to evaluate:
a = somethingThatScrewsUpHeads;
(* OwnValues[a] above stored in OwnValues *)
a[1]
a[2]
We get…
somethingThatScrewsUpHeads[1]
somethingThatScrewsUpHeads[2]
Is there an easy/flexible way to prevent OwnValues for any Name in DownValues? (Lemme guess… it’s possible, but there’s going to be a performance hit?)
I don’t know if this is an “accepted” way, but you could define a rule that prevents
SetandSetDelayedfrom acting upona:With this rule in place, any attempt to assign an
OwnValuetoawill fail:However, this rule will still allow new
DownValuesfora:Performance
The rule does not seem to have an appreciable impact on the performance of
SetandSetDelayed, presumably since the rule is installed as an up-value ona. I tried to verify this by executing…… both before and after the installation of the rule. There was no observable change in the timing. I then tried installing
Set-related up-values on 10,000 generated symbols, thus:Again, the timing did not change even with so many up-value rules in place. These results suggest that this technique is acceptable from a performance standpoint, although I would strongly advise performing performance tests within the context of your specific application.