I tried posting this on the Wolfram.com student forums, but got no response. A friend suggested that I try this forum as well.
I have a Mathematica question I'm hoping someone here can help with, because it seems fundamental, but it's been bothering me for a long time. My basic question is "is there a way pass a local variable to a function in a state between 'unevaluated' and 'evaluated,' which might correspond to something like 'dereferenced.'"
Here is a bit of code I've written which demonstrates the problem:
Clear[L, M, P, Q, k]
SetAttributes[L, HoldFirst];
L[Sum[x_, it_]] := Print["here."];
L[Times[x_, y_]] := Print["there."];
L[x_Symbol] := Print["nowhere."];
M[x_] :=
Module[{s},
s = Sum[x, {i, 1, 20}];
L[s]
];
P[x_] :=
Module[{s},
s = Unevaluated[Sum[x, {i, 1, 20}]];
L[s]
];
Q[x_] :=
Module[{s},
s = Unevaluated[Sum[x, {i, 1, 20}]];
L[Evaluate[s]]
];
Let me try to explain/motivate this. Suppose that L is some function which cares about the difference between summation and multiplication, and uses pattern matching to tell the difference. Suppose further that L receives input from some other function. I've shown three ways of writing that function: M, P, and Q. Here are the three functions, with their corresponding outputs:
In: M[k]
Out: nowhere.
In: P[k]
Out: nowhere.
In: Q[k]
Out: there.
None of these is what I want, which is "here," and which can be achieved by passing input directly to L:
In: L[Sum[k, {i, 1, 20}]]
Out: here.
Why don't the three functions M, P, and Q work? M and P leave "s" completely unevaluated, so that what L actually receives is a value like "s$123456". Q, on the other hand, evaluates "s" entirely, and arrives at "20*k". You may wonder, "but wait, that is what s evaluates to, why can't your code deal with that?" The simplest answer is that sometimes Mathematica seems to decide erroneously that the summation can be turned into multiplication, which leaves me with dummy variables from summations lying around unbound. Also, this is a problem at other times, such as when there is an appreciable difference between "x[[i]]-x[[i]]" and "0", because I really mean "x[[i]]" to stand in for some vector of as-yet-unknown length, so that it minus itself is a zero vector, which is different from plain 0.
So, does anyone know of a way to write a function which gets the expression out of "s", but doesn't evaluate it completely?