What is the difference between Set and SetDelayed when evaluating the RHS leaves it unchanged?
This is just my guess about what is going on. First, there is really an internal difference between the two approaches, as is shown in the OP. Another place where this difference manifests itself is with the function Language`ExtendedDefinition
:
Clear[f];
f[a_] = 2 + a;
Language`ExtendedDefinition[f]
Language`DefinitionList[f->{OwnValues->{},SubValues->{},UpValues->{},DownValues->{HoldPattern[f[a_]]->2+a},NValues->{},FormatValues->{},DefaultValues->{},Messages->{},Attributes->{}}]
Notice the Rule
instead of the RuleDelayed
in the DownValues
rule. For the SetDelayed
version:
Clear[g]
g[a_] := 2 + a
Language`ExtendedDefinition[g]
Language`DefinitionList[g->{OwnValues->{},SubValues->{},UpValues->{},DownValues->{HoldPattern[g[a_]]:>2+a},NValues->{},FormatValues->{},DefaultValues->{},Messages->{},Attributes->{}}]
This time the DownValues
rule uses RuleDelayed
.
So, I think the real question is why the output of DownValues
doesn't use Rule
:
Clear[f]
f[a_] = 2 + a;
DownValues[f]
{HoldPattern[f[a_]] :> 2 + a}
I think the answer is that if DownValues
did use Rule
, then the output would be confusing if a
had acquired a value after f
was defined. Suppose the output of DownValues
was:
dv = {HoldPattern[f[a_]] -> 2 + a}
{HoldPattern[f[a_]] -> 2 + a}
At some point, a
is given a value:
a = 3;
And then, later, the user wants to know the DownValues
of f
:
dv
{HoldPattern[f[a_]] -> 5}
The user would be confused into thinking that the RHS of the rule was 5
, when it is really 2+a
. So, the function DownValues
purposefully replaces Rule
with RuleDelayed
to avoid this confusion. Note that an alternative was to introduce another hold-type wrapper around the output of DownValues
, and this is actually what Language`ExtendedDefinition
does.
Also, it should be pointed out, that DownValues
are the same, but Definition
is still different. I guess this might be the "flag" op asked about.
Information
displays Definition
by calling it. While one might think Information
only "illustrates" whatever is kept internally, then probably Definition
really is what the kernel knows. Same output, but maybe a semantic difference one could say.
In[32]:= ClearAll[f, a]
f[a_] = a + 2
Definition[f]
f[a_] := a + 2
Definition[f]
Out[33]= 2 + a
Out[34]= Definition[f]
Out[36]= Definition[f]