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