side effects from setting variables
- To: mathgroup at yoda.ncsa.uiuc.edu
- Subject: side effects from setting variables
- From: CAMERON at midd.cc.middlebury.edu
- Date: Fri, 22 Feb 91 17:17 EST
I have thought of a potentially evil trick. I don't have a use
for it as yet, but I could think of a few. It came to me suddenly,
and it was so delightfully perverse that I wanted to share it.
The thought that led to this was the realization that in many
systems (including Mma) there are "magic variables" that cause
things to happen "behind the scenes" when their values are set.
This example shows that it's easy to make Mma do an arbitrary side
computation when setting a variable, and at the same time simulate
the setting of the variable so that querying the variable returns
what you'd expect.
Note: in the definition of "foo", the expressions "bar = bop = x" and
"arbitrary[x]" are just examples to show what can be done, but the
last two expressions "foo := x" and "x" are necessary -- and they
must be last, and in that order -- to make the "assignment" to "foo"
returned the assigned value at the time of the assignment and in future
evaluations of "foo".
Mathematica (NeXT) 1.2 (January 20, 1990) [With pre-loaded data]
by S. Wolfram, D. Grayson, R. Maeder, H. Cejtin,
S. Omohundro, D. Ballman and J. Keiper
with I. Rivin and D. Withoff
Copyright 1988,1989,1990 Wolfram Research Inc.
In[1]:= arbitrary[x_] := Print["An arbitrary function has been called on ",x]
In[2]:= foo/: Set[foo,x_] := (bar = bop = x; arbitrary[x]; foo := x; x)
In[3]:= {foo,bar,bop} (* initially, these have no value -- including foo! *)
Out[3]= {foo, bar, bop}
In[4]:= foo = 44 (* now the fun begins! *)
An arbitrary function has been called on 44
Out[4]= 44
In[5]:= {foo, bar, bop}
Out[5]= {44, 44, 44}
In[6]:= ?foo
foo
foo/: foo := 44
foo/: (foo = x_) := (bar = bop = x; arbitrary[x]; foo := x; x)
In[6]:= ?bar
bar
bar = 44
In[6]:= foo = 83 (* if we "reset" foo, the right things happen *)
An arbitrary function has been called on 83
Out[6]= 83
In[7]:= {foo,bar,bop}
Out[7]= {83, 83, 83}
In[8]:= ?foo
foo
foo/: foo := 83
foo/: (foo = x_) := (bar = bop = x; arbitrary[x]; foo := x; x)
In[8]:= ?bop
bop
bop = 83
In[8]:= t = 99
Out[8]= 99
In[9]:= foo = t^2 + 2
An arbitrary function has been called on 9803
Out[9]= 9803
In[10]:= ?foo
foo
foo/: foo := 9803
foo/: (foo = x_) := (bar = bop = x; arbitrary[x]; foo := x; x)
In[10]:= ?bar
bar
bar = 9803
In[10]:= Quit
That last assignment ("foo = t^2 + 2") was a test to verify that
the evaluated result "9803" and not the unevaluated form "t^2 + 2"
would be stored as the "value" of "foo".
--Cameron Smith
Mathematica maven and free-lance consultant
cameron at midd.cc.middlebury.edu