While reading this answer I feel confused. If we do not care any specific detail of the original question, then ybeltukov's answer essentially makes use of the following fact

h_[a___, G[x_, ___, y_], b___] ^:= y[x]
G[2, e]


This example shows that unlike Set, SetDelayed, TagSet and TagSetDelayed which imperatively require that the assignment is associated to some symbol called assignment tag, UpSet and UpSetDelayed can be used to make assignment associated to pattern object as well (like the h_ in this example).

However, when executing G[2, e] it seems that the evaluator treats the flat input G[2, e] as ghostHead_[G[2, e]] such that the user-defined UpValues for G can be applied.

I cannot understand this. I assume there is some very fundamental mechanism taking effect in this example. Could someone point out the missing knowledge?


I am also confused about the use of Simplify in ybeltukov's answer. Why Simplify can reduce G[2, e] to e[2]? I have not found any documentation revealing this.

Edit 2

As Szabolcs points out in the comment, because the StandardForm is by default used by the Front End for output, the plain input G[2,e] is evaluated to G[2,e] then wrapped as


which applies to the UpValues defined by

h_[a___, G[x_, ___, y_], b___] ^:= y[x]

where, according to the standard Wolfram Language evaluation process, the UpValues of G is used prior to the DownValues of StandardFrom, so that the DownValues of StandardFrom is shadowed.

This is a side effect of the Front End wrapping StandardForm to the output, but we may make use of it.

We can also understand ybeltukov's answer which is,

h_[a___, G[x_, ___, y_], b___] ^:= h[a, y[x], b]


where Simplify also acts as a wrapper whose DownValues is also shadowed, and according to the upvalue definition, Simplify[G[2,e]] is evaluated as Simplify[e[2]] which further reduces to e[2] according to the definition of Simplify.

With such understanding, we can replace the Simplify with StandardForm,


this will return the same result but with better efficiency, because StandardForm does not require searching for applicable transformation rules.

  • 3
    $\begingroup$ An insight: h_[a___, G[x_, ___, y_], b___] ^:= (Print@Hold@h[a, G[x, y], b]; y[x]) $\endgroup$
    – Kuba
    Apr 26 '15 at 7:03
  • $\begingroup$ It is not possible to associate an assignment with a pattern object. It must always be associated with a symbol. Here that symbol is G. The example you show creates an up-value of G. So how come G[2,e] evaluates at all? Since the definition is an up-value one, G[2,e] should only evaluate if it is wrapped by some head. Here it appears it isn't. What really happens is that as part of formatting, the FrontEnd does wrap G[2,e] in another head, which then triggers the UpValue evaluation. Running this example in a terminal, with no Front End, does nothing: G[2,e] doesn't evaluate. $\endgroup$
    – Szabolcs
    Apr 26 '15 at 16:12
  • $\begingroup$ I guess the morale is: UpValues of such generality are unsafe and are best avoided. $\endgroup$
    – Szabolcs
    Apr 26 '15 at 16:16
  • $\begingroup$ The mystery is where does the wrapper come from. It is almost certain that it is introduced by the Front End, but how and why? If we change the outermost head h_ to some certain symbol h, ie, h[a___, G[x_, ___, y_], b___] ^:= (Print@Hold@h[a, G[x, y], b]; y[x]) then the previous result e[2] is not obtained. This shows that the Front End picks the ghostHead it wraps to G[2,e]. There must be some mechanism used by the Front End, but the purpose is hidden. $\endgroup$
    – saturasl
    Apr 26 '15 at 21:12
  • 2
    $\begingroup$ @saturasl G[2,e] simply evaluates to itself. But the Front End will format every output as StandardForm by default. This formatting goes wrong and yields e[2] due to the UpValue $\endgroup$
    – Szabolcs
    Apr 27 '15 at 3:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.