[Prev][Next][Index][Thread]

Re: Need help with Class-Allocated Slots



In article 
<Pine.GSO.3.96.1000630114158.12937A-100000@tardis.tardis.ed.ac.uk>, 
Hugh Greene <q@tardis.ed.ac.uk> wrote:

> On Thu, 29 Jun 2000, Dustin Voss wrote:
> > In article 
> > <Pine.GSO.3.96.1000629115446.4116H-100000@tardis.tardis.ed.ac.uk>, Hugh 
> > Greene <q@tardis.ed.ac.uk> wrote:
> > 
> > > On Wed, 28 Jun 2000, Dustin Voss wrote:
> > > > In article <m3zoo8p02k.fsf@soma.andreas.org>, Andreas Bogk 
> > > > <andreas@andreas.org> wrote:
> > > > 
> > > > > "Scott McKay" <swm@mediaone.net> writes:
> > > > > 
> > > > > > During the design of Dylan, I proposed that class slots be
> > > > > > accessible by calling the accessor on the class object itself, 
> > > > > > but
> > > > 
> > > > I'm actually surprised this is even being considered.  The idea 
> > > > that class slots belong to the class itself is incorrect ...
> > > 
> > > Good exposition but I have to disagree :-)
> > 
> > Thanks!  I did what could to shine the light of truth on the sinners in 
> > Gamorrah...yup...
> 
> Said light being shone from the watch towers on the city walls of Sodom,
> of course ;-P
> 
> > > IMHO, as a philosophical point, I'd say that, as long as an idea 
> > > is consistent in itself and its context, it's not "incorrect"; it 
> > > may well be "useless"  or "unpopular", though ;-)  In particular, 
> > > the JOOP article I quoted yesterday specifically wanted "my" 
> > > behaviour from languages instead of "yours".
> > 
> > "The difference between theory and practice is that in theory, there is 
> > no difference, but in practice, there is."
> 
> Yes; but see below for some "in practice".
> 
> > Practical is nice.  But Dylan already handles methods and singletons 
> > differently than Java, why not this too?  And, actually, I wonder why 
> > the author of the JOOP article specifically wanted class slots to have 
> > that syntax.  Did the article say?
> 
> The author's reasons "[were] twofold:
> 
>  - To remove the use of global variables.  Reducing the need for global
>    data variables and methods implies also that the possibility of
>    conflicts due to name clashes is decreased.
> 
>  - To remove the need for so-called utility classes, i.e., classes with
>    only one instance."
> 
> I don't think either of these reasons work in Dylan, because we can have
> global functions (instead of utility classes) scoped by modules (instead
> of classes).
> 
> However, here's a more concrete reason, based on my programming 
> experience in Dylan, for wanting class slots to be accessible without 
> instances. Every once in a while you have a class for which creation 
> of instances may allocate some resources "elsewhere" (e.g., database 
> connections, Win32 GUI resources, etc.) and this allocation may be 
> expensive.  If you have to create an instance to access a class slot, 
> this may be unacceptable.


Ah, I see.  I'd recognized the problem, but didn't think it was the 
driving force behind this initiative.  Since it is, I'll have to rethink 
my position.


> Yes, you can have a compiler which recognises and optimises some 
> pattern for "faking" class-accessible class slots, as you say below.  
> In fact, you could have macros wrapping up these paterns (and even 
> effectively replace \class-definer; though making each-subclass slots 
> efficient would be hard, and O(1) very hard, I think).  However, one 
> of the great things about the Dylan language is how much it does for 
> you, and this is something else I'd like it to do :-)  Let me see if 
> I can address your reasons against it ...
> 
> > It's really the same principle as Dylan's singletons.  You can make 
> > as many instances of a singleton as you like.  It's just that all 
> > those instances refer to the same object.  ...
> 
> I assume you mean the "Singleton class" pattern implemented in Dylan, 
> rather than the "singleton()" type constructor.  If so, that's 
> something you can do in C++ and Java, too.  But although there's 
> definitely similarity, it's not similar enough in some cases, as I 
> explained above: you may have to pay an unacceptable cost to get at 
> the class state, if you don't already have an instance to hand.
>
> > Since I *do* come from a C++ background, both threw me.  But once I 
> > figured out the rationale, it made perfect sense.  Anyway, if we 
> > allow class slots to 'be' part of the class itself, we should 
> > similarly allow all slots of a singleton class to be 'part of' the 
> > class itself (i.e. treat all of a singleton's slots like class 
> > slots) to prevent mismatched concepts.
> 
> I disagree (I think -- I'm not sure I understand you here).  You want
> class slots in addition to instance slots when you want some state to be
> the same for all instances of a class and some to be different.  You want
> the Singleton class construction pattern when you only ever want one
> instance of a class, in which case the instance/class slot distinction is
> irrelevant.  (Unless you want subclasses of your Singleton class; in that
> case class slots could still be useful but each-subclass would be
> useless.) 


Right.  The Singleton pattern can be considered a class in which all the 
slots are class slots, and creating more than one instance is illegal.  
Since all the slots are effectively class slots, accessing a Singleton's 
slots should be the same as accessing a regular class's class slots.


> > > > Each class is an instance of <class>.  Conceptually, the lines
> > > > 
> > > > -------------------------------------
> > > > <my-class>.my-class-slot;
> > > > my-class-slot-getter (<my-class>);
> > > > -------------------------------------
> > > > 
> > > > imply that <my-class> has a slot called my-class-slot.  But it 
> > > > doesn't! 
> > > >  
> > > > <my-class> is an instance of <class>, not a sub-class of <class>.  
> > > 
> > > You're right here.  In terms of Dylan's half-hidden meta-object 
> > > protocol (MOP), this proposal is in effect allowing you to create 
> > > subclasses of <class>.  (Simplistically, one new subclass for 
> > > each such instance of <class>.)  We'd presumably still want to 
> > > keep <class> as a sealed class, so there'd have to be some 
> > > "magic" here.  However, there's already "magic" involved in 
> > > creating things like limited types ...
> > 
> > Well, let's keep things like that to a minimum.  I'm more comfortable 
> > with dot syntax for class slots as "syntactic sugar" than as "how the 
> > language actually works", if you take my meaning.
> 
> I'm not sure I do know exactly what you mean, but I can agree with
> avoiding magic and hackery as much as possible :-)  OTOH, Dylan already
> allows some (conceptually pretty clean) hackery for efficiency's sake,
> which is one of its major goals.


I mean, Dylan could understand "<my-class>.class-slot" to mean 
"make(<my-class>).class-slot", but Dylan should not understand it to 
mean the object "<my-class>" has a slot named "class-slot".

But since your concern is the overhead of making an instance... 


> Now that I think about it, though, it might actually work to make <class>
> an open abstract (instantiable? primary?) class (nevertheless containing
> whatever slots the implementation needs, though not exported).  There
> could be a sealed concrete subclass called, say <simple-class>, adding
> nothing other than sealing and "concretion" (if that's a word), and this
> is the class to which "make(<class>, ...)" would "down-delegate".
> 
> Then any invocation of \class-definer which contained "class" or
> "each-subclass" slots would create new instances or subclasses of 
> <class>.
> (I *think* I have the details figured out -- I can post them if you 
> like.)
> 
> However, the above would be unacceptable if it made Dylan too much more
> inefficient.  Any real Dylan implementation gurus care to analyse that
> possibility?  I suppose someone will, if I write this up as a language
> extension proposal ... :-)
>
> > ... I really don't like messing with standards. Sure, it's not handed
> > down from above, but the authors had sound theoretical reasons for
> > writing it they way they did: 
> 
> This is a sufficiently radical change that I wouldn't want to just "mess"
> with the standard.  I'd at least put it through the language
> change proposal process and possibly try to open up a "Dylan 2" standard
> -- many people have had other, more radical ideas :-)
> 
> As for "sound theoretical reasons", Scott McKay just recently said that
> "[David] Moon didn't like it because it confuses class vs. instance."  I
> don't think it does, personally (or at least, I can see a model where it
> doesn't -- there might be others where it does).


It seems like that would work, but I understand and agree with David 
Moon's objection.  What is this model that wouldn't cause confusion?


> > 1) If you think it through, like I did, it reinforces the concept 
> > that a class really is just a plain-jane instance of <class>, like 
> > any instance of any variable.  Adding class-accessible class slots 
> > makes a <class> special...
> 
> Right, but maybe we can open up the MOP a bit as I suggested above, 
> so that it needn't be special.  OTOH, even if we don't, doing "MOP 
> magic" for efficiency and convenience *does* fit with Dylan's 
> philosophy.  Limited types are *very* useful and quite intuitive; but 
> you can't (yet) write some of your own (e.g., limited(<binary-tree>, 
> of: <byte-string>)) and when you start to think about how to 
> implement them, it does get quite hairy.
> 
> > 2) ...and special cases should be kept to a minimum.
> 
> Yes, we're just debating where that minimum should lie ;-)  (And whether
> this really is a special case.)
> 
> > But again, a compiler that recognizes the idiom and optimizes it is 
> > okay by me, but it shouldn't be in the standard.
> 
> This on its own doesn't feel like a good argument to me, because you 
> could create a similar idiom to implement the current state of 
> affairs, which is in the standard (and which you're defending).  (I 
> acknowledge that this isn't your only argument, though.)
> 
> BTW, I hope all the above comes across in the spirit of constructive
> debate, not flamage.  Also, all IMHO, and I may change my mind :-)

No worries.  But, for every use of class variables I can think of right 
now (and there aren't many of those), it is more conceptually accurate 
to use global variables and getter/setter functions, anyway.



References: