Eliminating assignments and variable syntax (accessors)

Marcel Weiher marcel at system.de
Wed Aug 4 07:07:53 UTC 1999


> From: Alan Lovejoy <sourcery at pacbell.net>
>
> > ** Original Sender: Marcel Weiher <marcel at system.de>
> >
> > Exactly!  The difference to now is that right now I'd have to
> > manually modify the source code of all the methods doing access,   
> > whereas with the change the system can do the recompilation
> > automagically.
>
> It's bad enough that all methods have to be recompiled when the
> slot definitions are changed.  Such recompilation is inelegant,
> time consuming, brittle, and requires the compiler to be present
> in order for methods to be added or removed (and also for
> classes to be added or removed)--even when all added or changed
> methods are already precompiled.  Think of the consequences
> for moving behavior over the net!

I *have* thought about the consequences, and yes, they are bad.  The  
only point of the exercise is that they are a *little less bad* than  
today.  Today I have to rewrite, with the change the compiler can  
recompile.  Which part of "a little better" don't you understand?

> > I never suggested this was a panacea, just that it is a *little*   
> > better than what we have now.
> >
> > >  A worse problem
> > > is what to do when an accessor is introduced **in a subclass**. 
> > > Should that change the meaning of code in a superclass, or not? 
> >
> > Again, ask yourself what happens now.  There, you've got the  
initial
> > answer.
>
> What happens now is that is that no subclass can **inadvertently**  
> change the meaning of a direct variable access or assignment simply 
> by introducing an accessor or mutator method.  If the subclass decides 
> that the object in the instance variable should not be subject to  
external
> modification, it might define an accessor that answers a copy of the 
> value in the variable, thus breaking just about all existing code that 
> thought it was accessing the value in the variable, not a copy thereof. 

Well, you obviously misunderstood what I said.  I am saying that  
such an accessor defined in a subclass will not change the compiled  
direct access in the superclass, which is *exactly the same behaviour  
as today*.

The one change that actually *does* occur is when a *superclass*  
decides that the instance var should only be available through  
accessor.  This will, in fact, change what the subclasses see and  
disallow direct access, but that was exactly the idea.

The one problem I see is that now there would be now way for a  
subclass to bypass a complex accessor/mutator defined in a superclass  
and directly munge/access an instance variable without changing the  
code of the superclass.  Then again, this restriction may be viewed  
as a benefit.  (The workaround is to rename the instance var in the  
superclass).

> "Don't do that," you say.  That's all well and good when only one
> person ever makes changes to the code base.  What about in an
> environment where code from different sources is being merged
> dynamically, such as might happen with componets/modules/
> nameSpaces/image segments/parcels and so on and so forth?

Once again, these are valid points, but the exist in the same  
(actually slightly worse) form today!  What I am proposing is to make  
this situation *slightly* better and remove some unecessary syntax.

> > > Worse, suppose the accessor does lazy initialization, but  
there are
> > > references to the iVar where lazy initialization would be either 
> > > incorrect or at least undesirable?
> >
> > Then you shouldn't use the basic-accessor to do the lazy  
initialization.
>
> Which is a big change.  Currently, I can do lazy initialization  
using an
> accessor that has the same name as the variable.  This makes it  
transparent
> to the clients of the object whether I'm doing lazy initialization  
or not
> (it's none of their business, after all).

It's a trivial change because you just rename the instance variable  
to some hidden name.  After all your clients shouldn't be looking at  
the instance variable definitions at all, only at the message  
protocol.  If they are looking at inst-vars, then that is wrong and  
something I would be more than happy to break.

> 2. We extend the syntax for accessing instance variables, so that  
an instance
> variable can be accessed by prepending an underscore (for example) to 
> the name of the variable.  However, when a variable is accessed  
this way,
> a lookup is performed for a private method with the same name.  If none 
> is found (dynamically, at run time), then the variable is accessed  
directly.
> Otherwise, the private method is executed instead.
>
> So the expression "_name" would be evaluated as follows:
>
> 1. Try to send the selector #_name.
>
> 2. If such a method is found, execute it and push the result.
>
> 3. If no such method is found, push the value of the instance variable  
> "name."

If this is implemented at runtime as your description suggests, it  
would make instance variable access extremely inefficient by  
requiring a failed message send for inst-var access.  I don't see  
anybody actually using this as it is syntactically ugly *and* highly  
inefficient.  Furthermore, it *does* suffer from exactly the subclass  
overriding problem you thought you had spotted in my proposal (which  
mine actually doesn't).

If this is implemented at compile time, it is *exactly* my proposal  
except for your addition of the underscore character, which I find  
superfluous and which isn't possible anyhow in Smalltalk (apart from  
that matching several of the objections you had to my proposal).

> And the expression "_name := aString" would be evaluated as follows: 
>
> 1. Try to send the selector #_name: with "aString" as the argument. 
>
> 2. If such a method is found, execute it and push the result.
>
> 3. If no such method is found, assign "aString" to the instance
> variable "name."

I think this is a really bad idea, because := has the connotation of  
"munge this variable, now", which is exactly the type of operation  
and connotation 'we' are trying to get rid of here.  I don't see what  
the benefit could possibly be of keeping the notation, but changing  
its meaning into something much more complicated including possible  
message sends.

On the contrary, I for one would be extremely confused by having  
something that looks like a simple assignment trigger a message send.  
 OTOH, inlining a message send to self is really quite harmless.

Marcel





More information about the Squeak-dev mailing list