Re: Standard Evaluation with UpValues

• To: mathgroup at smc.vnet.net
• Subject: [mg19423] Re: [mg19355] Standard Evaluation with UpValues
• From: "Wolf, Hartmut" <hwolf at debis.com>
• Date: Mon, 23 Aug 1999 13:57:27 -0400
• Organization: debis Systemhaus
• References: <199908210309.XAA12600@smc.vnet.net.>
• Sender: owner-wri-mathgroup at wolfram.com

```Hello Ted,

Ersek, Ted R schrieb:
>
> Section 7.1.3 of the excellent book "Power Programming With Mathematica The
> Kernel" by David B. Wagner explains the main evaluation loop.  In that
> Section it indicates UpValues for a symbol are applied before DownValues for
> the symbol are applied.
>
> OK then consider the case below where (f) has both an UpValue and a
> DownValue defined by the user.
>
> At Out[4] the UpValue for (f) was used.  In that case the DownValue couldn't
> be used to evaluate f[t].
> Then at Out[5] the DownValue for (f) is used to evaluate  f[E] --> 1+E
> before the kernel checked to see if the UpValue would apply (and it would
> have).  I get the same result using Versions 3 and 4.
>
> When the kernel evaluates g[f[E]] it must figure out that the Head is (g)
> before it evaluates f[E].  After determining that the Head is (g) it checks
> to see if (g) has any Hold* attributes, and continues with evaluation as
> required.  So by the time the kernel evaluates f[E] it has all the
> information it needs to know that the UpValue for (f) can be used.  However,
> the DownValue is used instead.  Wait a minute, aren't UpValues applied
> before DownValues are applied?
>
> Can someone convince me that the main evaluation loop performs as explained
> by David Wagner when evaluating In[5] below?  Also can someone give a
> different example that more clearly shows that UpValues are used first?
> ------------------------------
>
> In[1]:=
> ClearAll[f,g,t];
> f[x_?NumericQ]:=1+x;
> f/:g[f[x_]]:=x+4;
>
>
> In[4]:=
> g[f[t]]
>
> Ou[4]=
> 4+t
>
>
> In[5]:=
> g[f[E]]
>
> Out[5]=
> g[1+E]
>
Before discussing let's look at the Traces:

In[9]:= g[f[t]] // Trace
Out[9]= {{f[t], {NumericQ[t], False}, f[t]}, g[f[t]], t + 4, 4 + t}

In[10]:= g[f[E]] // Trace
Out[10]= {{f[E], {NumericQ[E], True}, 1 + E}, g[1 + E]}

You see in *both* cases DownValues for f are tried before any UpValue,
only in the first case there survives an expression g[f[t]] which has an
UpValue that is applied (later). So there is no _miracle_ but consistent
behaviour! However is it right?

Just at the moment I don't have Stan Wagon's text at hand. However
looking into The Book, 4ed, at p.320, we read

"_Mathematica_ always tries upvalue definitions before downvalue ones."

Standing isolated as such, this seams to be in contradiction to our
observations. Such we have to look more closely for the context of the
statement. On next page we find the statement:

"Definitions associated with f are applied before definitions with g in
the expression g[f[x]]"   (I made a trivial substitution to adapt to out
example)

Observed behaviour is completely consistent with that, in fact we
haven't made any definitions for g.

So let's do that:

In[23]:= ClearAll[f, g, t]

In[24]:= g[f[x_?NumericQ]] := 1 + x

In[25]:= f /: g[f[x_]] := x + 4;

In[26]:= g[f[t]]
Out[26]= 4 + t

In[27]:= g[f[E]]
Out[27]= 4 + E

no difference! And that's the [contextual] meaning (in The Book, and
most probably also in "Power..."):

UpValues [for f] are applied before DownValues [of g]

quite straight, as we see when tracing

In[28]:= g[f[t]] // Trace
Out[28]= {g[f[t]], t + 4, 4 + t}

Compare this trace to Out[9] above!

```

• Prev by Date: Re: This is what UpValues are for
• Next by Date: Re: circumference of an ellipse
• Previous by thread: Standard Evaluation with UpValues
• Next by thread: Re: Standard Evaluation with UpValues