[squeak-dev] About classVariables

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
21 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] About classVariables

stephane ducasse
Hi

to my stupefaction I discovered that the classVariables of a class are  
not the same as the ones of its metaclass.

TheRoot classVarNames ~= TheRoot class classVarNames

Does any body have some ideas why this is like that?

For me this is a conceptual bug.

Stef

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] re: About classVariables

ccrraaiigg

Hi Stef--

 > To my stupefaction I discovered that the classVariables of a class are
 > not the same as the ones of its metaclass.
 >
 > TheRoot classVarNames ~= TheRoot class classVarNames
 >
 > Does any body have some ideas why this is like that? For me this is a
 > conceptual bug.

      Actually, metaclasses don't really have class variables at all.
Class variables are defined by Class, which is a sibling of Metaclass,
not a superclass. There's a method in Behavior which just answers a new
empty Set for classVarNames; this is what you're invoking when you
evaluate [TheRoot class classVarNames].

      I guess that's in there so that "explain" and "browse class var
refs" behave as someone in the past wanted them to. Do you have a need
which conflicts with this? Do you actually need to use TheRoot's class
variables in code where (TheRoot class) is the receiver?


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] re: About classVariables

Martin Beck-3
Craig Latta wrote:

>
> Hi Stef--
>
>> To my stupefaction I discovered that the classVariables of a class are
>> not the same as the ones of its metaclass.
>>
>> TheRoot classVarNames ~= TheRoot class classVarNames
>>
>> Does any body have some ideas why this is like that? For me this is a
>> conceptual bug.
>
>      Actually, metaclasses don't really have class variables at all.
> Class variables are defined by Class, which is a sibling of Metaclass,
> not a superclass. There's a method in Behavior which just answers a new
> empty Set for classVarNames; this is what you're invoking when you
> evaluate [TheRoot class classVarNames].
>
However,

TheRoot classPool = TheRoot class classPool

evaluates to true...

Regards,
Martin

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Paolo Bonzini-2
Martin Beck wrote:

> Craig Latta wrote:
>> Hi Stef--
>>
>>> To my stupefaction I discovered that the classVariables of a class are
>>> not the same as the ones of its metaclass.
>>>
>>> TheRoot classVarNames ~= TheRoot class classVarNames
>>>
>>> Does any body have some ideas why this is like that? For me this is a
>>> conceptual bug.
>
> TheRoot classPool = TheRoot class classPool
>
> evaluates to true...

Indeed, I would have expected classVarNames to be just "self classPool
keys" or "self classPool keys inject: '' into: ' [:a :b | a,b,' ']".

Paolo

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] re: About classVariables

ccrraaiigg

      Martin Beck writes:

 > TheRoot classPool = TheRoot class classPool
 >
 > evaluates to true...

      I'd say that's a bug (as is Behavior>>classVarNames answering an
empty Set), because the class variables for (TheRoot class) should be
those defined by Metaclass, if we're going to be consistent (the
behavior of the system would end up being the same, since the class pool
for Metaclass is empty). I also notice that Metaclass>>classPool was
added after Squeak 3.2.

      Paolo Bonzini writes:

 > Indeed, I would have expected classVarNames to be just "self classPool
 > keys" or "self classPool keys inject: '' into: ' [:a :b | a,b,' ']".

      For the reason above, I'd say that's wrong also.

      But again, I'm wondering what real difficulty is caused by this.


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Paolo Bonzini-2
>      I'd say that's a bug (as is Behavior>>classVarNames answering an
> empty Set),

Why? (#allClassVarNames is a different story).

> because the class variables for (TheRoot class) should be
> those defined by Metaclass, if we're going to be consistent (the
> behavior of the system would end up being the same, since the class pool
> for Metaclass is empty). I also notice that Metaclass>>classPool was
> added after Squeak 3.2.

Not really, class variables are explicitly defined to apply both on the
instance and on the class side.  So the class pool should be the same,
without any #theClass.

Paolo

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] re: About classVariables

ccrraaiigg

Hi Paolo--

 > > I'd say that's a bug (as is Behavior>>classVarNames answering an
 > > empty Set),
 >
 > Why? (#allClassVarNames is a different story).
 >
 > > because the class variables for (TheRoot class) should be
 > > those defined by Metaclass, if we're going to be consistent...

      You just quoted my answer, so I don't see why you're asking again.

 > ...class variables are explicitly defined to apply both on the
 > instance and on the class side.  So the class pool should be the same,
 > without any #theClass.

      The class pool for an instance of Metaclass should be the class
pool defined by Metaclass. So, for example, the class pool for (Array
class) should be the class pool defined by Metaclass. This is different
than the class pool for Array or an instance of Array, which is the
class pool defined by Array.

      Again, until someone cites a reason why this is of practical
significance, I don't think it's a very interesting issue.


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] re: About classVariables

Eliot Miranda-2
In reply to this post by Martin Beck-3


On Mon, Oct 13, 2008 at 2:02 AM, Martin Beck <[hidden email]> wrote:
Craig Latta wrote:
>
> Hi Stef--
>
>> To my stupefaction I discovered that the classVariables of a class are
>> not the same as the ones of its metaclass.
>>
>> TheRoot classVarNames ~= TheRoot class classVarNames
>>
>> Does any body have some ideas why this is like that? For me this is a
>> conceptual bug.
>
>      Actually, metaclasses don't really have class variables at all.
> Class variables are defined by Class, which is a sibling of Metaclass,
> not a superclass. There's a method in Behavior which just answers a new
> empty Set for classVarNames; this is what you're invoking when you
> evaluate [TheRoot class classVarNames].
>
However,

TheRoot classPool = TheRoot class classPool

evaluates to true...

Regards,
Martin

One fix is to add the following method:
------------8<-----------
!Metaclass methodsFor: 'class variables' stamp: 'eem 10/13/2008 12:37'!
classVarNames
"Answer a Set of the names of the class variables defined in the receiver's instance."

^thisClass classVarNames! !
------------8<-----------
c.f. Metaclass>>classPool.

But a better fix is to move Class>>classVarNames to ClassDescription:
------------8<-----------
'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 13 October 2008 at 12:41:36 pm'!

!ClassDescription methodsFor: 'class variables' stamp: 'eem 10/13/2008 12:41'!
classVarNames
"Answer a Set of the names of the class variables defined in the receiver."

^self classPool keys! !

Class removeSelector: #classVarNames!
------------8<-----------

Whoever said that the class variables of a metaclass should be those of Metaclass is very wrong.  Code compiled in  the context of a metaclass includes the class variables of the non-metaclass (metaclass's instance), otherwise one couldn't access class variables in class-side methods.


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About classVariables

Eliot Miranda-2
In reply to this post by stephane ducasse


On Sun, Oct 12, 2008 at 1:11 PM, stephane ducasse <[hidden email]> wrote:
Hi

to my stupefaction I discovered that the classVariables of a class are not the same as the ones of its metaclass.

TheRoot classVarNames ~= TheRoot class classVarNames

Does any body have some ideas why this is like that?

For me this is a conceptual bug.

Its just a vanilla bug because Class>>classVarNames is defined in the wrong place.  It should be defined in ClassDescription.  See my previous message.
 


Stef




Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Nicolas Cellier-3
In reply to this post by Eliot Miranda-2
Eliot Miranda a écrit :

>
>
> On Mon, Oct 13, 2008 at 2:02 AM, Martin Beck
> <[hidden email] <mailto:[hidden email]>>
> wrote:
>
>     Craig Latta wrote:
>      >
>      > Hi Stef--
>      >
>      >> To my stupefaction I discovered that the classVariables of a
>     class are
>      >> not the same as the ones of its metaclass.
>      >>
>      >> TheRoot classVarNames ~= TheRoot class classVarNames
>      >>
>      >> Does any body have some ideas why this is like that? For me this
>     is a
>      >> conceptual bug.
>      >
>      >      Actually, metaclasses don't really have class variables at all.
>      > Class variables are defined by Class, which is a sibling of
>     Metaclass,
>      > not a superclass. There's a method in Behavior which just answers
>     a new
>      > empty Set for classVarNames; this is what you're invoking when you
>      > evaluate [TheRoot class classVarNames].
>      >
>     However,
>
>     TheRoot classPool = TheRoot class classPool
>
>     evaluates to true...
>
>     Regards,
>     Martin
>
>
> One fix is to add the following method:
> ------------8<-----------
> !Metaclass methodsFor: 'class variables' stamp: 'eem 10/13/2008 12:37'!
> classVarNames
> "Answer a Set of the names of the class variables defined in the
> receiver's instance."
>
> ^thisClass classVarNames! !
> ------------8<-----------
> c.f. Metaclass>>classPool.
>
> But a better fix is to move Class>>classVarNames to ClassDescription:
> ------------8<-----------
> 'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 13 October
> 2008 at 12:41:36 pm'!
>
> !ClassDescription methodsFor: 'class variables' stamp: 'eem 10/13/2008
> 12:41'!
> classVarNames
> "Answer a Set of the names of the class variables defined in the receiver."
>
> ^self classPool keys! !
>
> Class removeSelector: #classVarNames!
> ------------8<-----------
>
> Whoever said that the class variables of a metaclass should be those of
> Metaclass is very wrong.  Code compiled in  the context of a metaclass
> includes the class variables of the non-metaclass (metaclass's
> instance), otherwise one couldn't access class variables in class-side
> methods.
>
>
> ------------------------------------------------------------------------
>
>

It is funny with Object because:

     (Object class allSuperclasses includes: Object).

So the Object classPool keys will be accessible twice (It does not seem
to hurt).

Nicolas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] re: About classVariables

ccrraaiigg
In reply to this post by Eliot Miranda-2

Hi Eliot--

 > Whoever said that the class variables of a metaclass should be those
 > of Metaclass is very wrong. Code compiled in the context of a
 > metaclass includes the class variables of the non-metaclass
 > (metaclass's instance), otherwise one couldn't access class variables
 > in class-side methods.

      I think you're confusing metalevels. If I compile a class-side
method for Array, and I use a class variable, conceptually it's one of
Array's class variables I'm using, yes? What the class variables of
(Array class) might be is irrelevant. Yes, during compilation,
Metaclass>>scopeHas:ifTrue: delegates to the receiver's sole instance,
but that doesn't mean that a metaclass has the same class variables as
its sole instance.

      To say otherwise is to introduce a conceptual inconsistency into
the system: the class variables of an object are defined by its class,
except if that object is a metaclass. Further, suppose the class
variables pool for Metaclass were not empty. By your logic instances of
Metaclass don't have access to it.

      I guess we disagree here.


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Nicolas Cellier-3
In reply to this post by Nicolas Cellier-3
nicolas cellier a écrit :

>
> It is funny with Object because:
>
>     (Object class allSuperclasses includes: Object).
>
> So the Object classPool keys will be accessible twice (It does not seem
> to hurt).
>
> Nicolas
>
>
>

Nah, forget it, it does not work that way...

UndefinedObject class>>someSuperObsolete
     ^ObsoleteSubclasses

would not reach this class var definition though:

   (Behavior classVarNames includes: #ObsoleteSubclasses and: [
      UndefinedObject class allSuperclasses includes: Behavior].

Which is confirmed by:

   UndefinedObject class allClassVarNames includes: #ObsoleteSubclasses.

There is definitely some trick here...


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Nicolas Cellier-3
In reply to this post by ccrraaiigg
Craig Latta a écrit :

>
> Hi Eliot--
>
>  > Whoever said that the class variables of a metaclass should be those
>  > of Metaclass is very wrong. Code compiled in the context of a
>  > metaclass includes the class variables of the non-metaclass
>  > (metaclass's instance), otherwise one couldn't access class variables
>  > in class-side methods.
>
>      I think you're confusing metalevels. If I compile a class-side
> method for Array, and I use a class variable, conceptually it's one of
> Array's class variables I'm using, yes? What the class variables of
> (Array class) might be is irrelevant. Yes, during compilation,
> Metaclass>>scopeHas:ifTrue: delegates to the receiver's sole instance,
> but that doesn't mean that a metaclass has the same class variables as
> its sole instance.
>
>      To say otherwise is to introduce a conceptual inconsistency into
> the system: the class variables of an object are defined by its class,
> except if that object is a metaclass. Further, suppose the class
> variables pool for Metaclass were not empty. By your logic instances of
> Metaclass don't have access to it.
>
>      I guess we disagree here.
>
>
> -C
>
> --
> Craig Latta
> improvisational musical informaticist
> www.netjam.org
> Smalltalkers do: [:it | All with: Class, (And love: it)]
>
>
>

That's how it works indeed, but the example I provided sounds then like
very misleading (a bug?):

UndefinedObject class allClassVarNames includes: #ObsoleteSubclasses.

which is a class var of Behavior...


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

ccrraaiigg
In reply to this post by ccrraaiigg

      A couple of elaborations...

 > If I compile a class-side method for Array, and I use a class
 > variable, conceptually it's one of Array's class variables I'm using,
 > yes? What the class variables of (Array class) might be is irrelevant.
 > Yes, during compilation, Metaclass>>scopeHas:ifTrue: delegates to the
 > receiver's sole instance, but that doesn't mean that a metaclass has
 > the same class variables as its sole instance.

      In particular, in Metaclass>>scopeHas:ifTrue: we're referring to
the scope defined by the receiver of the method we're compiling (Array),
not the object being asked this scope question (Array class). There's
probably a better name than "scopeHas:".

 > To say otherwise is to introduce a conceptual inconsistency into
 > the system: the class variables of an object are defined by its class,
 > except if that object is a metaclass. Further, suppose the class
 > variables pool for Metaclass were not empty. By your logic instances
 > of Metaclass don't have access to it.

      That is, having put an entry into the class variables pool for
Metaclass, if I then ask (Array class) for its class variable names, I
won't get the new class variable name in my answer if it just delegates
to its sole instance.


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

ccrraaiigg
In reply to this post by Nicolas Cellier-3

Hi Nicolas--

 > That's how it works indeed, but the example I provided sounds then
 > like very misleading (a bug?):
 >
 > UndefinedObject class allClassVarNames includes: #ObsoleteSubclasses.
 >
 > which is a class var of Behavior...

      (UndefinedObject class) is an instance of Metaclass, and Metaclass
is a subclass of Behavior, so I would expect Behavior's class variable
names to show up in a list of all the class variables names for
(UndefinedObject class).

      I swear I'm getting real work done. ;)


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

Nicolas Cellier-3
Craig Latta a écrit :

>
> Hi Nicolas--
>
>  > That's how it works indeed, but the example I provided sounds then
>  > like very misleading (a bug?):
>  >
>  > UndefinedObject class allClassVarNames includes: #ObsoleteSubclasses.
>  >
>  > which is a class var of Behavior...
>
>      (UndefinedObject class) is an instance of Metaclass, and Metaclass
> is a subclass of Behavior, so I would expect Behavior's class variable
> names to show up in a list of all the class variables names for
> (UndefinedObject class).
>

Well not exactly... I make a parallel reasonning:

nil is an instance of UndefinedObject, UndefinedObject is a subclass of
Object, so I expect Object's class variable names to show up in a list
of all the class variables names for nil

nil doesNotUnderstand: #allClassVarNames

It runs through (UndefinedObject class superclasses) rather than
(UndefinedObject class class).

UndefinedObject class < Object class < ProtoObject class < Class <
ClassDescription < Behavior

>      I swear I'm getting real work done. ;)
>

Oh yes, this thread is really bound to be unproductive.
You do not need to answer this!

>
> -C
>
> --
> Craig Latta
> improvisational musical informaticist
> www.netjam.org
> Smalltalkers do: [:it | All with: Class, (And love: it)]
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] re: About classVariables

Eliot Miranda-2
In reply to this post by ccrraaiigg


On Mon, Oct 13, 2008 at 1:20 PM, Craig Latta <[hidden email]> wrote:

Hi Eliot--


> Whoever said that the class variables of a metaclass should be those
> of Metaclass is very wrong. Code compiled in the context of a
> metaclass includes the class variables of the non-metaclass
> (metaclass's instance), otherwise one couldn't access class variables
> in class-side methods.

    I think you're confusing metalevels. If I compile a class-side method for Array, and I use a class variable, conceptually it's one of Array's class variables I'm using, yes? What the class variables of (Array class) might be is irrelevant. Yes, during compilation, Metaclass>>scopeHas:ifTrue: delegates to the receiver's sole instance, but that doesn't mean that a metaclass has the same class variables as its sole instance.

When compiling code in Foo class, as opposed to Foo, the compiler asks Foo class to lookup variables, not Foo.  Hence if the code refers to a class inst var of Foo it will be in scope because this class inst var will be one of Foo class's inst vars.  Similarly, when the compiler asks Foo class to bind a variable that is actually a class variable of Foo, it is up to Foo class to look in Foo's class pool, not the compiler.

So it makes sense to me that Foo class's class pool is the same as Foo's.

    To say otherwise is to introduce a conceptual inconsistency into the system: the class variables of an object are defined by its class, except if that object is a metaclass. Further, suppose the class variables pool for Metaclass were not empty. By your logic instances of Metaclass don't have access to it.

The only place that instances of Metaclass have access to Metaclass's class pool is in methods on Metaclass.  Class-side methods in metaclasses other than Metaclass class do _not_ have access to Metaclass class variables.  Try it :)



    I guess we disagree here.



-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]





Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] re: About classVariables

stephane ducasse
In reply to this post by Eliot Miranda-2
> One fix is to add the following method:
> ------------8<-----------
> !Metaclass methodsFor: 'class variables' stamp: 'eem 10/13/2008  
> 12:37'!
> classVarNames
> "Answer a Set of the names of the class variables defined in the  
> receiver's instance."
>
> ^thisClass classVarNames! !
> ------------8<-----------
> c.f. Metaclass>>classPool.
>
> But a better fix is to move Class>>classVarNames to ClassDescription:
> ------------8<-----------
> 'From Croquet1.0beta of 11 April 2006 [latest update: #1] on 13  
> October 2008 at 12:41:36 pm'!
>
> !ClassDescription methodsFor: 'class variables' stamp: 'eem  
> 10/13/2008 12:41'!
> classVarNames
> "Answer a Set of the names of the class variables defined in the  
> receiver."
>
> ^self classPool keys! !
>
> Class removeSelector: #classVarNames!
> ------------8<-----------
>
> Whoever said that the class variables of a metaclass should be those  
> of Metaclass is very wrong.  Code compiled in  the context of a  
> metaclass includes the class variables of the non-metaclass  
> (metaclass's instance), otherwise one couldn't access class  
> variables in class-side methods.

Tx

Stef

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] About classVariables

stephane ducasse
In reply to this post by Eliot Miranda-2
Yeap.
I was shocked :)
this is good to know that this was already fixed in Croquet.
Stef

> Hi
>
> to my stupefaction I discovered that the classVariables of a class  
> are not the same as the ones of its metaclass.
>
> TheRoot classVarNames ~= TheRoot class classVarNames
>
> Does any body have some ideas why this is like that?
>
> For me this is a conceptual bug.
>
> Its just a vanilla bug because Class>>classVarNames is defined in  
> the wrong place.  It should be defined in ClassDescription.  See my  
> previous message.
>

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: About classVariables

ccrraaiigg
In reply to this post by Eliot Miranda-2

Hi Eliot--

 > When compiling code in Foo class, as opposed to Foo, the compiler
 > asks Foo class to lookup variables, not Foo.

      I didn't say it would (although when looking for Foo's class
variables, (Foo class) will delegate to Foo).

 > Hence if the code refers to a class inst var of Foo it will be in
 > scope because this class inst var will be one of Foo class's inst
 > vars.

      No, it's in scope because it's a class inst var of *Foo*, like you
said in the first part of your sentence. :) In particular, the class
instance variable will have been put in the encoder's scopeTable by an
earlier invocation of Encoder>>init:context:notifying:.

 > Similarly, when the compiler asks Foo class to bind a variable that is
 > actually a class variable of Foo, it is up to Foo class to look in
 > Foo's class pool, not the compiler.

      You're referring to Metaclass>>scopeHas:ifTrue:, which does indeed
  delegate to the receiver's sole instance. But in that method "scope"
refers to the scope associated with the intended receiver of the method
we're compiling (Foo), not the object being asked this scope question
(Foo class). This doesn't say anything about what the class variables of
(Foo class) are, only that (Foo class) is responsible for answering the
class variables of Foo when compiling methods to be run with Foo as
receiver.

 > > To say otherwise is to introduce a conceptual inconsistency into
 > > the system: the class variables of an object are defined by its
 > > class, except if that object is a metaclass. Further, suppose the
 > > class variables pool for Metaclass were not empty. By your logic
 > > instances of Metaclass don't have access to it.
 >
 > The only place that instances of Metaclass have access to Metaclass's
 > class pool is in methods on Metaclass.

      As I clarified in a followup message, I was referring to what a
metaclass should answer as its class variables, not how to bind anything
during compilation of methods for which that metaclass will be the
receiver (those would just be instance-side methods of Metaclass, as you
say). For example, having put an entry into the class variables pool for
Metaclass, if I then ask (Array class) for all its class variable names,
I won't get the new class variable name in my answer by your logic.

 > Class-side methods in metaclasses other than Metaclass class do _not_
 > have access to Metaclass class variables.  Try it :)

      Eh? I never said that any of those methods should be able to bind
class variable names from Metaclass. I was talking about what one should
get when asking a metaclass point-blank for all its class variable names
(something that never happens as far as I can remember, hence the
exquisite angels-on-the-head-of-a-pin nature of this conversation :).


-C

--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]


12