[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: