# Dispatch displays rules incorrectly and evaluates when displaying

Bug introduced in 10.0.0 and fixed in 10.0.1

Consider this

a = 3;
disp = Dispatch[Unevaluated[{a -> 2}]]


We see the rule 3 -> 2, rather than a -> 2. However, we have

Unevaluated[a] /. disp

2 (*not 3*)


So that indeed the rule in the dispatch table was a -> 2. Note however that

Unevaluated[a] /. Normal[disp]

3


As Normal[disp] intermediately evaluates to a -> 2 which evaluates to 3 -> 2. a does not match 3, so there is no replacement. So at first sight it may seem reasonable that Dispatch displays the table this way. However, this may lead to side effects

Side effects

Consider the following example. First we just set disp2, without displaying it.

disp2 = Dispatch[Unevaluated[{Print["hello"] -> 2}]];

 Null (*prints nothing, note the semicolon*)


but when we do display the Dispatch table, the message is printed.

Note that we can still use the Dispatch table however.

Unevaluated[Print["hello"]] /. disp2

2


This seems quite weird to me. To me it seems reasonable to put any expression in a Dispatch table. But it is not nice at all that such expressions would be evaluated when we display the Dispatch table. I suppose the way around this is to use HoldPattern, but that is disappointing to me, because really this should not be necessary.

Comparison with Association

To see why this is disappointing, consider Association. Here it is crucial that we use Unevaluated, as it is not an option to use HoldPattern, as the following does not work.

(*b has no value*)
Association[HoldPattern[b] -> 2][b]

Missing["KeyAbsent", b]


For a, which does have a value, we would have to do

Association[Unevaluated[a -> 2]][Unevaluated[a]]

2


Quick fix

Note that evaluating the following will prevent this issue.

Unprotect[Dispatch];
Clear@Dispatch;
Protect[Dispatch];


This only clears the rules that determine how Dispatch tables are displayed.

Question

So all in all it's nothing too major, I just wanted to share this. It is not nice that Dispatch can have side effects when used in this reasonable way. Is this a bug?

A perfect answer would "spelunk" to where to code is evaluated.

-
You certainly are good at finding edge cases. It wouldn't occur to me to try to use Unevaluated inside Dispatch. Associations are a whole new beast to wrangle however. Thanks as always for interesting, if long ;-), questions. –  Mr.Wizard Jul 16 '14 at 13:42
@Mr.Wizard then I will be brief this time :). If you wish to know where the idea came from, just read the entire edit history of all my posts :P. –  Jacob Akkerboom Jul 16 '14 at 13:50
Its an undesired behaviour but patterns are expected to evaluated, I am not sure I would suggest avoiding HoldPattern even if it wasn't strictly necessary –  Rojo Jul 16 '14 at 16:07
@Rojo well, even Cases and ReplaceRepeated work "correctly" with Unevaluated: a = 3; c = 2; {Hold[a] //. Unevaluated[{a -> c, c -> b}], Cases[Hold[a], Unevaluated[p : a :> Hold[p]]]}. I think that relative to other users I can very much about correct handling of expressions that should not be evaluated, so this probably doesn't work with a lot code other users have made. But as long as the internal functions handle lists of rules "correctly", I like this alternative. Fortunately, symbol updates can no longer break Dispatch tables.. –  Jacob Akkerboom Jul 16 '14 at 16:40
–  Szabolcs Jul 16 '14 at 19:00

That happens during the blob creation. You can switch that off with

SetSystemOptions["TypesetOptions"->"IconicElidedForms"->False]

-

Yes, this is a minor evaluation leak in the formatting rules for the Dispatch summary box. You can certainly work around it by setting that system option (one of the reasons it is there is preceisly these sorts issues), but the cost is all summary boxes will be disabled, even nice and useful ones like for InterpolatingFunction and SparseArray (which should have no leaks in them given how they are constructed). In the particular case of Dispatch, the only thing that would be removed by Clear'ing it is the summary box code. As a low-level, raw object, most of code is built into the kernel and not user-accessible in any event. So your original approach may be a better, more target appracoh (depending on your needs).

As for the evaluation leak, I will file a bug for it and look at it, though probably not until August. It's not super hard bug, but it is a five minute fix, either, so I'll need to find the time to look at it seriously.

-
Thank you for the answer and for filing the bug. It is good to know that my hypothesis about Clear was right. –  Jacob Akkerboom Jul 16 '14 at 19:15
@JacobAkkerboom This issue is now fixed and should make its way into version 10.0.1. –  Itai Seggev Aug 6 '14 at 4:37