I'll first state the main question of this, what follows afterwards are some of my thoughts/attempts at fixing it and additional questions about possible improvements (getting an answer to those would be great of course, but I'll try to focus the question on one issue)

I'm trying to incorporate a modified version of this answer into my utility package, but I have problems attaching usage information to it. The current version looks like this:


Due to the second and third line, the following works:


but this does not:


First, I assumed that ? was simply an alias for Information, but this doesn't seem to be the case. Tracing the second call (Trace@?•) reveals that the symbol gets immediately replaced by "•", the upvalues only breaking things deeper inside Information. Even HoldComplete is not enough:

(* HoldComplete[Information["•", LongForm -> False]] *)

Question: Is there any way to fix this, short of Unprotecting Information and adding a definition for "•"? And what is ?? (Judging from the documentation of HoldComplete, it seems to be an "input transformation", as anything else would have not been evaluated)

Additional notes/attempts/questions/...

The issue is that the upvalue associated with wreaks havoc when trying to work with the symbol itself (e.g. getting Information or UpValues of ). I did a few things trying to fix this:

  • Ensure that the expression has at least one more argument, since something like f[•] wouldn't make much sense anyway. This fixes UpValues and similar functions
  • Reroute Information to display the usage message for •Proxy, which has no dangerous upvalues (therefore the first example above works)

There are several problems with this, one of which is that forcing more than one argument has unforeseeable consequences if the function does anything too complicated with its argument:

    f[x_] := -x > 0
    (* (Function[Null, -##1, {HoldAll}] > 0)[3] *)

I could of course implement a head blacklist for the upvalue of , but is there a way that is more elegant?


1 Answer 1


A partial answer is given here: Infix form of PutAppend ( >>> ) does not work with variable

? has special parsing behavior unlike most other syntax. As Itay says it is "auto-stringifying" and since you cannot attach an UpValue to a String I see no direct solution to this issue.

The two work-arounds that come to mind you have already mentioned, unprotecting Information to attach a rule to it, or filtering h_ in the •/:h_[pr___,•,pst___] pattern. But for the sake of operating within a Notebook you could make a replacement at the Box level with $PreRead, e.g.:

$PreRead = # /. RowBox[{"?", "•"}] :> RowBox[{"?", "•Proxy"}] &;

Equivalently using MakeExpression so as not to encumber $PreRead:

MakeExpression[RowBox[{"?", "•"}], fmt_] :=
  MakeExpression[RowBox[{"?", "•Proxy"}], fmt]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.