Here is the typical case:
In[672]:= Clear[f]
In[673]:= test = g[f[a]]
Out[673]= g[f[a]]
'test' contains an expression containing an unevaluated function call to f
In[674]:= test
Out[674]= g[f[a]]
Now we give f a definition, and confirm that Mathematica 'knows' the
expression held by 'test' needs to be reevaluated:
In[675]:= f[x_] := x^2;
In[676]:= test
Out[676]= g[a^2]
So far as expected, but now we define f in a way that allows it to be
switched on and off without actually changing its definition:
In[677]:= Clear[f]
In[679]:= switch = False;
In[680]:= f[x_] := x^2 /; switch
In[681]:= test = g[f[a]]
Out[681]= g[f[a]]
In[682]:= switch = True;
Here we see that Mathematica fails to notice that the expression can be
further evaluated - the expression in 'test' is metastable.
In[683]:= test
Out[683]= g[f[a]]
Some processes obviously cause complete evaluation:
In[684]:= Uncompress[Compress[test]]
Out[684]= g[a^2]
Others, rather surprisingly, do not!
(Dialog) In[687]:= test /. f -> f
(Dialog) Out[687]= g[f[a]]
I don't really consider metastable expression to be a bug - more a
curiosity - and it would be undesirable to slow Mathematica processing
to try to fix this.
However, metastable expressions, do give a window into the methods
Mathematica uses to minimise the reevaluation of expressions. For
example, it might be interesting to repeat the above 10000 times with
different symbols, to determine if Mathematica is always consistent in
this regard.
I have never seen this effect discussed, so I would be interested in
links to previous discussions, if any.
David Bailey
http://www.dbaileyconsultancy.co.uk
This is a known effect. There is a special command Update, used in such
cases to force Mathematica to propagate changes like the one you discuss.
For the case at hand:
In[86]:= ClearAll[f];
test = g[f[a]]
Out[87]= g[f[a]]
In[88]:= switch = False;
f[x_] := x^2 /; switch
In[90]:= test
Out[90]= g[f[a]]
In[91]:= switch = True;
In[92]:= test
Out[92]= g[f[a]]
In[93]:= Update[f];
test
Out[94]= g[a^2]
I have an impression that switches in conditions are a major source of such
situations (at least, I was bitten by this more than once and every time in
this setting). My guess is that the reason may be that patterns and
definitions are optimized internally for a faster dispatch, and not
re-evaluating such conditional switches may be a part of the optimization,
as you suggested.
Regards,
Leonid
It is, in some views, an error, to define and implement a programming
language with a semantics that is not deterministic, but depends on (for
example) on the page in random access memory on which an expression is
stored, to tell how it will be evaluated.
Or call Update.
I suspect this "feature" is unique to Mathematica among programming
languages commercially supported. The fact that this is "known" to some
people does not make it harmless. The fact that it almost never affects
people does not make it harmless either.
RJF
I do not see how this feature (of needing Update to handle conditional
dependencies) is nondeterministic. Certainly it is documented in a way
that implies it would be deterministic with respect to memory layout.
See Documentation Center > Update > Basic Examples.
As for harmlessness, I'd suggest that use of conditional definitions in
a way that would require Update is, in effect, signing a release form.
Something to the effect "I am a mature programmer and understand that my
funky code might have unanticipated consequences. I will debug it as
needed and not make a huge fuss over it on Usenet. (Did I mention that I
am a mature programmer?)"
Getting to the issue raised of design philosophy, I will comment that a
language not requiring an Update would probably be less well able than
Mathematica to emulate infinite evaluation. Some people like that
feature of evaluation semantics, others do not. While it predates my
time here, I am fairly sure infinite evaluation was an intentional
aspect of the Mathematica design. (Would be ironic, though, if we today
were all adhering to what was originally a coding error that escaped the
laboratory...)
Daniel Lichtblau
Wolfram Research
In practice, I find that the exhaustive execution feature of
Mathematica, is extremely useful, and if it is necessary to leave an
obscure exception like this, for the sake of efficiency, well so be it.
David Bailey
http://www.dbaileyconsultancy.co.uk