MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Set::setps error? Twitter.m's OOP-like approach?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg104811] Re: Set::setps error? Twitter.m's OOP-like approach?
  • From: Erik Max Francis <max at alcyone.com>
  • Date: Tue, 10 Nov 2009 06:02:59 -0500 (EST)
  • References: <hconr9$1lj$1@smc.vnet.net> <hcr7jc$8nb$1@smc.vnet.net>

ragfield wrote:
> On Nov 3, 2:58 am, Erik Max Francis <m... at alcyone.com> wrote:
>> The deposit function doesn't work, though:
>>
>> In[6]:= a = create["test", 100]
>>
>> Out[6]= Account["test", 100]
>>
>> In[7]:= getBalance[a]
>>
>> Out[7]= 100
>>
>> In[8]:= deposit[a, 25]
>>
>> During evaluation of In[8]:= Set::setps: Account[test,100] in the part
>> assignment is not a symbol. >>
>>
>> Out[8]= 125
>>
>> In[9]:= getBalance[a]
>>
>> Out[9]= 100
>>
>> But here's what I'm confused; if I do what getBalance does manually, it
>> works fine:
>>
>> In[10]:= a[[BALANCE]] += 25
>>
>> Out[10]= 125
>>
>> In[11]:= a
>>
>> Out[11]= Account["test", 125]
>>
>> The Set::setps error is about Blocks so I suppose I'm running into some
>> scoping issue but I don't follow what it is.  What am I missing here?
>> What's the right way to write getBalance?
> 
> By the time deposit[] is called "a" has already evaluated to Account
> ["test", 100], which means a[[BALANCE]] += 25 at that point really
> means 100 += 25.  What you are looking for is "call by reference"
> behavior, and the way to get it is to use one of the Hold*
> attributes.  In this case you want to first argument of your deposit[]
> function to remain unevaluated so the actual symbol "a" is passed into
> the function in rather than the value of "a".

This is true but here's what's confusing me, and it's obviously a 
misunderstanding of how Mathematica treats objects and what object 
mutation means in Mathematica (if indeed that's really allowed in any 
meaningful sense in Mathematica).  If we continue where I left off, I 
can't mutate the value of `a` as above, but I _can_ test it against the 
global value of `a` with the `===` operator and verify that it's the 
same object (repeating just enough of the definitions to get the idea):

In[67]:= {NAME, BALANCE} = Range[2];
create[name_, balance_] := Account[name, balance]
getName[account_Account] := account[[NAME]]
getBalance[account_Account] := account[[BALANCE]]
deposit[account_Account, amount_] := account[[BALANCE]] += amount

In[90]:= a = create["globals", 100]

Out[90]= Account["globals", 100]

In[91]:= isTheSameAsTheGlobalAQ[account_Account] := account === a

In[92]:= x = a

Out[92]= Account["globals", 100]

In[95]:= isTheSameAsTheGlobalAQ[x]

Out[95]= True

So I can verify it's the same object, but I can't mutate it -- that 
generates the aforementioned Set::setps error.  But doing it manually 
with a itself works fine.  How come?  What is it about Mathematica and 
values that I'm not getting?  It's obviously something fundamental, but 
I haven't encountered it in a book before.

Clearly Mathematica has a more functional approach, so what I'm doing is 
naughty anyway.  Do I take it that the idea of mutating an object in a 
local context and expecting it to have wider-ranging results (as, say, 
in other languages like Python or Java or Lisp) is just simply mistaken?

-- 
Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
  San Jose, CA, USA && 37 18 N 121 57 W && AIM/Y!M/Skype erikmaxfrancis
   Can I walk with you / 'Till the day that my heart stops beating
    -- India Arie


  • Prev by Date: Re: Give arrow a certai color
  • Next by Date: Re: Plotting with dotted lines solved (Re:
  • Previous by thread: Re: Set::setps error? Twitter.m's OOP-like approach?
  • Next by thread: Re: Re: Set::setps error? Twitter.m's OOP-like approach?