Bug introduced in 10.0 and persisting through 11.0.1 or later
Bug introduced in 10.0 and fixed in 10.4
Association
is new in 10.0.
Bug still present: AssociationMap[Hold, p]
Fixed bug: Hold /@ p
Jacob Akkerboom commented:
Note that
PositionIndex
does work correctly with held expressions, whereas this is a bit painful to implement usingGatherBy
.a = 1; PositionIndex[Unevaluated[{a, b, c, d}]]
I finally got around to exploring this behavior and I am a bit confused and troubled by what I see.
First Jacob's example with a more explicit definition of a
:
a = "Fail!";
p = PositionIndex[Unevaluated[{a, b, c, d}]]
<|a -> {1}, b -> {2}, c -> {3}, d -> {4}|>
We see from this that Association
is capable of containing unevaluated key names. We can also extract the value corresponding to the key, or use the Association in a replacement:
p[Unevaluated @ a]
Hold[a, b, c] /. p
{1} Hold[{1}, {2}, {3}]
Other operations prove problematic however. In the first and third cases a
evaluates undesirably:
Hold /@ p
KeyMap[Hold, p]
AssociationMap[Hold, p]
<|"Fail!" -> Hold[{1}], b -> Hold[{2}], c -> Hold[{3}], d -> Hold[{4}]|> <|Hold[a] -> {1}, Hold[b] -> {2}, Hold[c] -> {3}, Hold[d] -> {4}|> Association[{Hold["Fail!" -> {1}], Hold[b -> {2}], Hold[c -> {3}], Hold[d -> {4}]}]
Since KeyMap
does work I thought we could use HoldPattern
for the keys, but that too has problems in that the original lookups and replacements no longer work:
p2 = KeyMap[HoldPattern, p]
<|HoldPattern[a] -> {1}, HoldPattern[b] -> {2}, HoldPattern[c] -> {3}, HoldPattern[d] -> {4}|>
p2[Unevaluated @ a]
Lookup[p2, Unevaluated[a]]
Hold[a, b, c] /. p2
Missing["KeyAbsent", "Fail!"] Missing["KeyAbsent", Unevaluated[a]] Hold[a, b, c]
The lookup does work if we use an explicit HoldPattern
but that seems somewhat undesirable:
p2[HoldPattern @ a]
{1}
To make the replacement work we can convert the Association to a Dispatch
expression:
Hold[a, b, c] /. Dispatch[p2]
Hold[{1}, {2}, {3}]
My questions:
Is there a better way to work with unevaluated keys in an Association?
Is the illustrated behavior intended and desirable?
Are unevaluated keys an expected application of
Association
? The behavior ofPositionIndex
indicates it may be but the conflicting results of the mapping operators seem unplanned.
Association
with unevaluated keys usingPositionIndex
then puts us in a strange situation. I think maybe this should be considered a bug ofPositionIndex
. Maybe it does not make sense to expect anything fromAssociationMap
in this case, as this case is so unusual, so that maybe this should not be marked as a bug inAssociationMap
. $\endgroup$