Re: "dereference" variable
- To: mathgroup at smc.vnet.net
- Subject: [mg82068] Re: [mg82033] "dereference" variable
- From: Sseziwa Mukasa <mukasa at jeol.com>
- Date: Thu, 11 Oct 2007 00:18:54 -0400 (EDT)
- References: <200710100822.EAA26488@smc.vnet.net>
On Oct 10, 2007, at 4:22 AM, Todd Johnson wrote: > 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, Since L is HoldFirst it doesn't evaluate its arguments, M and P therefore evaluate the expression L[s] and s is obviously a symbol so they apply the appropriate rule. Q forces evaluation of s which forces evaluation of the expression Sum[k, {i, 1, 20}], the Unevaluated is lost because it was used in the previous Set expression, there are no statements in Mathematica everything is an expression including assignment. k was already substituted for x by the pattern matcher. Sum[k,{i,1,20}] evaluates to Times[20,k] which has head Times and the appropriate expression for L is then evaluated. You can see all of this using Trace. > 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, It's not erroneous you need to follow the evaluation sequence, Mathematica does not operate the way languages like C or Java do, it uses a strict read eval loop, it reads an expression checks if there's a rule that can be used to evaluate it and continues doing so until there is nothing left to evaluate. For that matter the idea of references and passing by value or reference does not map well. > which leaves me with dummy variables from summations lying around > unbound. What variables are unbound? I don't see any. > 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. Again you are fighting the evaluation sequence, if you don't want to evaluate x[[i]]-x[[i]] because you are going to define an evaluation rule for x later, you shouldn't evaluate that expression until the right time. > So, does anyone know of a way to write a function which gets the > expression out of "s", but doesn't evaluate it completely? There's no expression to get out of s, once the assignment is done s has a value: 20 x_ in this case. Furthermore at any time the sees an expression Sum[x,{i,1,20}] it will evaluate it, the only way to stop this is to either override the evaluation of Sum by defining new rules which is not recommended or not to use Sum but use your own expression that you evaluates to the what you expect eg. s=mySum[x,{k,1,20}] L[mySum[x__]]:=Print["here"] Regards, Ssezi
- References:
- "dereference" variable
- From: Todd Johnson <johnsong@ics.uci.edu>
- "dereference" variable