Return-Path:
Date: Mon, 22 Feb 93 16:28:55 GMT-0600
From: Bill Dudney
To: gnu-objc@gnu.ai.mit.edu
Subject: Class Variables
Hi All,
I have been thinking about class variables and I dont see a reason, in the runtime system,
why we could not put them into the language. The problem I see is in the syntax of doing
this. Maybe we could use something like @classVar or @ivars and @cvars (@ivars
assumed) for differentiating between the two. What do you all think?
Thanks,
Bill Dudney
Return-Path:
Date: Tue, 23 Feb 1993 00:16:40 +0100
From: Kresten Krab Thorup
To: Bill Dudney
Cc: gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302222228.AA01434@>
Subject: Class Variables
Bill Dudney writes:
>I have been thinking about class variables and I dont see a reason,
>in the runtime system, why we could not put them into the language.
>The problem I see is in the syntax of doing this. Maybe we could use
>something like @classVar or @ivars and @cvars (@ivars assumed) for
>differentiating between the two. What do you all think?
You're right, I see no reason for not to have class variables either.
There are several things like this. For instance, implementing some
kind of blocks as known in Smalltalk (using gcc nested functions)
would be another good idea. I have plenty of ideas like this... :-)
However, we *must* have the runtime finished before we can afford to
use time for exploring such issues.
/Kresten
Return-Path:
From: Bill Shirley
Date: Mon, 22 Feb 93 16:53:27 -0600
To: Bill Dudney
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
> Hi All,
>
> I have been thinking about class variables and I dont see a reason, in the
> runtime system, why we could not put them into the language. The problem I
> see is in the syntax of doing this. Maybe we could use something like
> @classVar or @ivars and @cvars (@ivars assumed) for differentiating
> between the two. What do you all think?
I prefer a simpler (in my mind) syntax like...
@interface MyClass : Object
{
id instanceVar;
static int instanceCount;
}
what do you think about overworking the 'static' keyword a little more?
>
> Thanks,
>
>
> Bill Dudney
>
>
---
Bill Shirley NeXTmail accepted
Internet: BShirley%Wiltel@relay1.uu.net USENET: ? uunet!wiltel!bshirley ?
Voice: (713) 364-4124
Return-Path:
Date: Mon, 22 Feb 93 18:32:16 GMT-0500
From: alta@starr.com (Rex Riley)
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: rr86@cunixa.cc.columbia.edu
Bill Dudney
> Maybe we could use something like @classVar or @ivars and @cvars
>(@ivars assumed)
Break ------------------------- < Einstein Reality Check >
"Everything should be made as simple as possible, but not simpler."
--
How much complexity for simplicity's sake? Will Gnu Obj-C join the
C++ race for most powerful, expressive, and complex language?
-r
----------------------------- Continue
Return-Path:
Date: Tue, 23 Feb 93 00:50:59 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: wiltel!bshirley@uunet.uu.net
Cc: dudney@pencom.com, gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302222253.AA07241@wtg20.> (message from Bill Shirley on Mon, 22 Feb 93 16:53:27 -0600)
Subject: Class Variables
I like `static' for this. This is a natural extension
of its usual meaning, and is also what C++ uses for the same idea.
Return-Path:
Date: Tue, 23 Feb 1993 09:09:25 -0500
From: Paul Murphy
To: rms@gnu.ai.mit.edu
Cc: wiltel!bshirley@uunet.uu.net, dudney@pencom.com, gnu-objc@gnu.ai.mit.edu
In-Reply-To: Richard Stallman's message of Tue, 23 Feb 93 00:50:59 -0500 <9302230550.AA09085@geech.gnu.ai.mit.edu>
Subject: Class Variables
I don't like the idea of keywords having different meanings depending on
their context. Since C and ObjC are often mixed with great liberty you
really can start to think of this as context and not *only* language.
If I write a C function in a file that implements some ObjC methods I
can end up with the same keyword having two meanings only a few lines
apart.
Besides, I don't think C++ is a very good example for many things,
especially syntax.
Date: Tue, 23 Feb 93 00:50:59 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
I like `static' for this. This is a natural extension
of its usual meaning, and is also what C++ uses for the same idea.
Return-Path:
Date: Tue, 23 Feb 93 11:31:07 -0600
From: lupson@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Cc: lupson@geom.umn.edu
Reply-To: lupson@geom.umn.edu
Rex Riley writes:
> How much complexity for simplicity's sake? Will Gnu Obj-C join the C++
> race for most powerful, expressive, and complex language?
Class variables would seem to be a small, simple, and useful extension to
the language. Both Paul and I have recently run into the need for the
kind of functionality that class variables would provide. Currently this
functionality is implemented with static variables, but that approach
unfortunately complicates subclassing. It would seem to me that using
static variables for class management makes the language more complex than
using class variables.
An alternate approach within the current language would be to make a
single instance of a "class manager" object and use it (instead of the
class object) to do bookkeeping. However, this is ugly.
One issue that has not been brought up yet is what impact class managed
instances would have on distributed objects (regardless of whether it is
implemented as class variables, static variables, or class manager
objects). If you have proxies flying around and you ask a class something
like [MyClass numberOfInstances] you would have a problem. On the other
hand, things might just work out in the wash if the use of class variables
is limited to "accepting the responsibility" of creating something. The
difference is between every instance of a class having -the same- watchful
parent, and every instance of a class having -some- watchful parent. In
one sense omitting class variables (an making it harder to do class
management) can be a good thing in that it forces objects to be better
behaved in a distributed environment.
Bill Dudney writes:
> I prefer a simpler (in my mind) syntax like...
> @interface MyClass : Object
> {
> id instanceVar;
> static int instanceCount;
> }
This looks like it could easily get confusing. I would prefer a new
keyword like "class int myClassVar" or something like @classVariables and
@instanceVariables (with @instanceVariables implied by default). I would
also avoid abbreviations...
#impt
@inf myObj:Obj
{
@cvar
int i;
@ivar
@priv
char *c;
@prot
int j;
@pub
void *dat;
}
@end
We don't want another creat on our conscience.
Linus Upson
The Geometry Center
lupson@geom.umn.edu
Return-Path:
From: Steve_Naroff@NeXT.COM (Steve Naroff)
Date: Tue, 23 Feb 93 08:23:23 -0800
To: rms@gnu.ai.mit.edu (Richard Stallman)
Subject: Class Variables
Cc: wiltel!bshirley@uunet.uu.net, dudney@pencom.com, gnu-objc@gnu.ai.mit.edu
Language implementors may find the use of static natural (for class
variables), but I am not sure developers will see the beauty.
Objective-C currently offers 2 compelling advantages over C++:
(1) it has a dynamic runtime.
(2) it is much simpler and easier to learn (than C++).
I hope these advantages are considered when extending the language.
Nevertheless, your point about C++ using it for the same idea makes
sense, especially since so many people are learning OOP through C++.
Note that C++ is particularly conservative about introducing new
keywords, which makes it hard to learn. "virtual foo() = 0" is a
pretty obscure way of introducing (what I think) is a really
important concept (abstract classes).
It seems to me that "static" doesn't describe the feature, it
describes the implementation. If the keyword described the feature
(@classVariable, or whatever), we are free to have both static and
dynamic implementations. When working with an OODB vendor recently,
the need came up for dynamic class variables that could be added at
runtime.
regards,
snaroff.
Begin forwarded message:
Date: Tue, 23 Feb 93 00:50:59 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: wiltel!bshirley@uunet.uu.net
Cc: pencom.com!dudney@uunet.uu.net,
gnu.ai.mit.edu!gnu-objc@uunet.uu.net
In-Reply-To: <9302222253.AA07241@wtg20.> (message from Bill Shirley
on Mon, 22 Feb 93 16:53:27 -0600)
Subject: Class Variables
I like `static' for this. This is a natural extension
of its usual meaning, and is also what C++ uses for the same idea.
Return-Path:
From: Nik_Gervae@NeXT.COM (Nik Gervae)
Date: Tue, 23 Feb 93 11:02:13 -0800
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Bill Dudney wrote:
> > I have been thinking about class variables and I dont see a reason, in the
> > runtime system, why we could not put them into the language. The problem I
> > see is in the syntax of doing this. Maybe we could use something like
> > @classVar or @ivars and @cvars (@ivars assumed) for differentiating
> > between the two. What do you all think?
Bill Shirley replied:
> I prefer a simpler (in my mind) syntax like...
>
> @interface MyClass : Object
> {
> id instanceVar;
> static int instanceCount;
> }
>
> what do you think about overworking the 'static' keyword a little more?
Now that seems elegant to me. It does have some semantic problems, though.
My first thought on seeing this, knowing what I do about private ivars,
might be that the overloaded meaning is "@private", not "shared among
instances". It's the idea of scope reduction that occurs in this
scenario.
On the other hand, you could regard it as the idea of static in a function
definition being "shared among invocations", parallelling the idea of a
variable "shared among instances." Now *that* ties in very nicely to what
we're trying to do.
--
Nik "not an Objective C guru" Gervae
Software Publications ## S2/8bg+-l+y++-/:!z-n-++o-+/++:x-+:a++:u-+v+:j+-p(eR)
NeXT Computer, Inc. ## B2(go-t & sburns)f-t+c-!g-(--)k--s---mr-p+
ngervae@next.com ## [[[[NXDisclaimer alloc] init] disclaim] free];
Return-Path:
From: Kenneth Lerman
X-Mailer: SCO System V Mail (version 3.2)
To: murphy@murphy.gun.com, rms@gnu.ai.mit.edu
Subject: Re: Class Variables
Cc: dudney@pencom.com, gnu-objc@gnu.ai.mit.edu, wiltel!bshirley@murphy.gun.com
Date: Tue, 23 Feb 93 16:32:45 EST
Re:
Date: Tue, 23 Feb 93 00:50:59 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
I like `static' for this. This is a natural extension
of its usual meaning, and is also what C++ uses for the same idea.
The problem I have with this is that I believe that class and instance
variable definitions should be kept separate from each other to avoid
confusion. Of course, Stallman's suggestion would not preclude
someone with my preference from putting unnecessary (from a language
point of view) divisions in his program.
Ken
--
Kenneth Lerman ...!uunet!casey!gaboon!seltd!lerman
Systems Essentials Limited (203)426-4430
55 Main Street
Newtown, CT 06470
Return-Path:
Date: Tue, 23 Feb 93 15:56:36 -0600
From: burchard@geom.umn.edu
To: Nik_Gervae@NeXT.COM (Nik Gervae)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Nik_Gervae@NeXT.COM (Nik Gervae) writes:
> Bill Shirley replied:
>
> > I prefer a simpler (in my mind) syntax like...
> >
> > @interface MyClass : Object
> > {
> > id instanceVar;
> > static int instanceCount;
> > }
> >
> > what do you think about overworking the 'static' keyword a
> > little more?
> [...]
>
> On the other hand, you could regard it as the idea of static
> in a function definition being "shared among
> invocations", parallelling the idea of a variable
> "shared among instances." Now *that* ties in very nicely
> to what we're trying to do.
Actually, the "shared instance variable" concept does not really
fulfill my idea of the purpose of a "class variable". This concept
seems to imply that the variable in question is directly accessible
to instances, but not necessarily accessible to the class object.
What I had in mind was more something like a meta-instance-variable:
something directly accessible to the class object, and perhaps (given
a sufficiently benevolent class method) available to its instances as
well. It is definitely necessary for many applications that the
class be able to access this variable whether or not any instances
exist.
(The bottom line is that classes need to be as much like objects as
possible---why deny the benefits of OOP to OOP itself?)
--------------------------------------------------------------------
Paul Burchard
``I'm still learning how to count backwards from infinity...''
--------------------------------------------------------------------
Return-Path:
Date: Tue, 23 Feb 93 16:58:48 -0600
From: burchard@geom.umn.edu
To: Nik_Gervae@NeXT.COM (Nik Gervae)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
How about this...
We already define instance and class _methods_ in the same place, but
use (+) and (-) to distinguish them. Why not do the same with
instance and class variables (i.e., variables visible within the
scope of instance and class methods, respectively)?
@interface MyClass
{
@-
// variables visible within instance methods
id anInstanceVariable;
@+
// variables visible within class methods
id aClassVariable;
}
+ classGetsThisOne;
// self is the class; aClassVariable is in scope
- instanceGetsThisOne;
// self is an instance; anInstanceVariable is in scope
@end
Return-Path:
Date: Tue, 23 Feb 93 17:32:04 -0600
From: lupson@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: lupson@geom.umn.edu
Paul Burchard writes:
> How about this...
> @interface MyClass
> {
> @-
> // variables visible within instance methods
> id anInstanceVariable;
> @+
> // variables visible within class methods
> id aClassVariable;
> }
I'd take it one step further...
@interface MyClass:MySuperClass
{
+ id aClassVariable;
- id anInstanceVairable;
}
@end
("-" would be implied when no modifier is present.)
Linus Upson
The Geometry Center
lupson@geom.umn.edu
Return-Path:
Date: Tue, 23 Feb 93 17:07:53 GMT-0600
From: Bill Dudney
To: Steve_Naroff@next.com (Steve Naroff)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
>Begin forwarded message:
>
>From: Steve_Naroff@next.com (Steve Naroff)
>Date: Tue, 23 Feb 93 08:23:23 -0800
>To: rms@gnu.ai.mit.edu (Richard Stallman)
>Subject: Class Variables
>Cc: @uunet.uu.net:wiltel!bshirley, @uunet.uu.net:pencom.com!dudney,
> @uunet.uu.net:gnu.ai.mit.edu!gnu-objc
>
>
>Language implementors may find the use of static natural (for class variables), but I am
>not sure developers will see the beauty.
>
>Objective-C currently offers 2 compelling advantages over C++:
>
>(1) it has a dynamic runtime.
>(2) it is much simpler and easier to learn (than C++).
>
>I hope these advantages are considered when extending the language.
>
>Nevertheless, your point about C++ using it for the same idea makes sense, especially
>since so many people are learning OOP through C++.
As was noted eairler C++ is not a very good model to start from. I would argue that many
people do not learn OOP/OOA from C++ (dont want a flame). It is just to easy not to do
OOP with C++ you can get away with murdering the OO paradigm.
>
>Note that C++ is particularly conservative about introducing new keywords, which makes
>it hard to learn. "virtual foo() = 0" is a pretty obscure way of introducing (what I think) is a
>really important concept (abstract classes).
I think instead of conservative you mean liberal if so I would agree. A good argument for
not adding new keywords or other strangeness (i.e. virtual). But IMHO @classVariables is
not "to much" and would not be a large addition.
>
>It seems to me that "static" doesn't describe the feature, it describes the implementation.
>If the keyword described the feature (@classVariable, or whatever), we are free to have
>both static and dynamic implementations. When working with an OODB vendor recently,
>the need came up for dynamic class variables that could be added at runtime.
Indeed! IMHO the feature would be best added and easiest to use through some feature
as @classVariable or what ever. I can see the point that we dont want to add many new
key words (no C++) but I think this is a usefull feature.
BTW I think you can already add class variables dynamically on a NeXT with some of the
runtime functions, then change them with other functions i.e. objc_createIvarList(),
objc_addIvars(), object_getClassVariable()...
Again, I think this would be a useful additional and I have enjoyed this thread.
Thanks,
Bill
>
>regards,
>
>snaroff.
>
[rms comments deleted]
Return-Path:
Date: Tue, 23 Feb 93 17:14:20 GMT-0600
From: Bill Dudney
To: Nik_Gervae@next.com (Nik Gervae)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
[some of the thread deleted]
>Now that seems elegant to me. It does have some semantic problems, though.
>My first thought on seeing this, knowing what I do about private ivars,
>might be that the overloaded meaning is "@private", not "shared among
>instances". It's the idea of scope reduction that occurs in this
>scenario.
Nik hit on something I had not thought about earlier, if we do use static wouldnt the ivar be
"in scope" in the instance methods, or was rms saying we would add a bigger definition to
static (in the scope of ivar declarations) that would limit the scope of the variable to class
methods?
>
>On the other hand, you could regard it as the idea of static in a function
>definition being "shared among invocations", parallelling the idea of a
>variable "shared among instances." Now *that* ties in very nicely to what
>we're trying to do.
>
>--
>Nik "not an Objective C guru" Gervae
>Software Publications ## S2/8bg+-l+y++-/:!z-n-++o-+/++:x-+:a++:u-+v+:j+-p(eR)
>NeXT Computer, Inc. ## B2(go-t & sburns)f-t+c-!g-(--)k--s---mr-p+
>ngervae@next.com ## [[[[NXDisclaimer alloc] init] disclaim] free];
What Nik, you work at NeXT and are not an Obj-C guru!!??? I am so disapointed!
HaVE fun,
Bill
Return-Path:
Date: Tue, 23 Feb 93 20:40:18 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: dudney@pencom.com
Cc: Steve_Naroff@next.com, gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302232307.AA01993@> (message from Bill Dudney on Tue, 23 Feb 93 17:07:53 GMT-0600)
Subject: Class Variables
It was a mistake to design the syntax of Objective C using the special
keywords that start with @.
This made the language incoherent. It looks like two parts grafted
together--rather than like a natural whole. It could instead have
been done with C-like syntax, making a unified language.
This was a hasty job. It is not something to take as an inspiration.
**NOTE** This is a matter of syntax; it has nothing to do with the
semantic differences between Objective C and C++.
Return-Path:
From: Bill Shirley
Date: Tue, 23 Feb 93 16:29:49 -0600
To: gnu-objc@gnu.ai.mit.edu, Nik_Gervae@NeXT.com
Subject: Re: Class Variables
>
> From:
>
> Nik_Gervae@NeXT.COM (Nik Gervae) writes:
> > Bill Shirley replied:
> >
> > > I prefer a simpler (in my mind) syntax like...
> > >
> > > @interface MyClass : Object
> > > {
> > > id instanceVar;
> > > static int instanceCount;
> > > }
> > >
> > > what do you think about overworking the 'static' keyword a
> > > little more?
> > [...]
> >
> > On the other hand, you could regard it as the idea of static
> > in a function definition being "shared among
> > invocations", parallelling the idea of a variable
> > "shared among instances." Now *that* ties in very nicely
> > to what we're trying to do.
>
> Actually, the "shared instance variable" concept does not really fulfill
> my idea of the purpose of a "class variable". This concept seems to imply
> that the variable in question is directly accessible to instances, but not
> necessarily accessible to the class object.
I definately agree with you that the the class variable 'belongs to the class
object', and I think most people mean this when they say it. We've basically
(as i see it) only been bickering over syntax.
I envisioned (without thinking much about it) the instance methods having access
to the class variables *as well as* the class methods. If, however, someone wants
to argue that the class variables belong to the class and only class methods can
directly reference them, you'll not get to much argument from me (because that will
force nicer code, and eliminate some posible dangers).
[example of what I just said]
I had seen
- init
{
[super init];
instanceCount++;
return self;
}
but i'll go along with...
+ incrementInstanceCount
{
instanceCount++;
return self;
}
- init
{
[super init];
[[self class] incrementInstanceCount];
return self;
}
but, *definately* the class methods should be able to access the class variables
reguardless of the existance of instances.
>
> What I had in mind was more something like a meta-instance-variable:
> something directly accessible to the class object, and perhaps (given a
> sufficiently benevolent class method) available to its instances as
> well. It is definitely necessary for many applications that the class be
> able to access this variable whether or not any instances exist.
what he -----^ said
>
> (The bottom line is that classes need to be as much like objects as
> possible---why deny the benefits of OOP to OOP itself?)
exactly, each class is only an instance of Class
>
> --------------------------------------------------------------------
> Paul Burchard
> ``I'm still learning how to count backwards from infinity...''
> --------------------------------------------------------------------
>
>
Bill Shirley
'bickering over semantics or being pedantic?'
BShirley%Wiltel@relay1.uu.net
Return-Path:
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Date: Wed, 24 Feb 93 10:10:43 -0500
From: rs05@gte.com
X-Mts: smtp
regarding Class vars, Linus Upson wrote:
> I'd take it one step further...
>
> @interface MyClass:MySuperClass
> {
> + id aClassVariable;
> - id anInstanceVairable;
> }
> @end
>
> ("-" would be implied when no modifier is present.)
this is the best proposal I've seen. makes perfect sense,
given this is the way methods are defined as well. it would
read nicely in the @interface header files. I also liked the
part about class variable scoping rules following the
conventions established for instance variables, so that
'aClassVariable' would be accessible to class methods.
Richard Stallman wrote:
> It was a mistake to design the syntax of Objective C using the special
> keywords that start with @.
>
> This made the language incoherent. It looks like two parts grafted
> together--rather than like a natural whole. It could instead have
> been done with C-like syntax, making a unified language.
Nobody disputes that the @-stuff and the [obj: msg] stuff
looks like an alien invasion of our beloved C homeland.
But ... that's what it is SUPPOSED to be. Obj-C does not
hide the fact that it is a layer on top of C. It does not
pretend to be a stand-alone language; it is a simple graft
of Smalltalk messaging syntax plus some class construction
frobbery onto vanilla C structs. Inventing new keywords
(or reusing old ones) to try and 'integrate' the two more
closely will only serve to confuse matters.
The 'beauty' (if you can call it that) of ObjC is in its
simplicity and 'separateness' as a pure extension layer
on top of C. If you want to add new features, you should
stick with the conventions that have already been established,
even though you may disagree with them. Consistency counts.
For implementation stuff, go crazy; use sparse arrays and
whatever else to make this tortoise run like a rabbit. Just
don't ignore ten-plus years of language evolution by doing
some hasty gene-splicing to make the tortoise LOOK like a
rabbit. It is what it is.
--Russ
rs05@gte.com
Return-Path:
From: Nik_Gervae@NeXT.COM (Nik Gervae)
Date: Wed, 24 Feb 93 10:19:36 -0800
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class variables
The talk about class variables only being accessible by the class object
indicates the distinction between (strictly) class variables, which only
the class object sees, and class-instance variables, which the class
object and all instances see. I think I heard somewhere that Smalltalk
has both of these...? My personal preference would be to have just class-
instance variables, rather just class-only variables. If we could manage
both flavors, I might like that, too (then again, I might start wondering
if this OOP thing is really worth all the trouble ;-).
--
Nik Gervae
Software Publications ## S2/8bg+-l+y++-/:!z-n-++o-+/++:x-+:a++:u-+v+:j+-p(eR)
NeXT Computer, Inc. ## B2(go-t & sburns)f-t+c-!g-(--)k--s---mr-p+
ngervae@next.com ## [[[[NXDisclaimer alloc] init] disclaim] free];
Return-Path:
From: ssircar@canon.com (Subrata Sircar)
Date: Wed, 24 Feb 93 10:27:35 -0800
To: rms@gnu.ai.mit.edu (Richard Stallman)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Reply-To: ssircar@canon.com
rms@gnu.ai.mit.edu (Richard Stallman) writes (about the "@" keywords):
>This made the language incoherent. It looks like two parts
>grafted together--rather than like a natural whole. It
>could instead have been done with C-like syntax, making a
>unified language.
I disagree. As someone who knew C (and CLU) before learning Objective-C, the @
keywords were actually helpful; they told me what was going on. The keywords
are clear and specify exactly what they mean, making reading and learning such
code simpler and easier. I'm not sure what C-like syntax would meet this goal.
[As an aside, I'm probably not looking at the problem from a language
designer's point of view, but rather as someone who was learning it for the
first time. From that perspective, the keywords are easy to learn, as opposed
to some tricks of C-syntax.]
Mostly, the keywords seemed to avoid clumsy or unclear syntax; but I don't
think that C-like syntax is an inspiration anyway. I would rather see
additional keywords than overloading of C-syntax, especially if the meaning is
not crystal clear.
In this particular case, I don't think "static" captures the idea of class
variables quite correctly - I'd rather see @classVar and @instanceVar, or some
variation thereof.
---
Subrata Sircar|ssircar@canon.com (NextMail ok)|Prophet & SPAMIT Charter Member
Canon Information Systems and I do not share the same views on everything.
"I'm just mad that I missed the sexual revolution." - me
"Yes, but you dress much better as a result." - Mike
Return-Path:
From: Steve_Naroff@NeXT.COM (Steve Naroff)
Date: Wed, 24 Feb 93 10:33:30 -0800
To: gnu-objc@gnu.ai.mit.edu
Subject: @-madness
Cc: rms@gnu.ai.mit.edu (Richard Stallman), dudney@pencom.com, snaroff@NeXT.COM
Russ @ gte wrote:
Nobody disputes that the @-stuff and the [obj: msg] stuff
looks like an alien invasion of our beloved C homeland.
But ... that's what it is SUPPOSED to be.
Exactly. The @-keywords were used so that Objective-C would be fully
upward compatible with existing C source code. It was a goal to "stay
out of C's way", as opposed to "build a better C" (ala C++). I can't
say that it is an "inspiration", but it supports the goal.
In fact, originally classes were introduced with "=" and ended with
"=:". Version 4.0 of Objective-C (which I worked on @ Stepstone)
changed this to @implementation/@end...which are a bit more
understandable! Nevertheless, +/- were maintained because they were
easy to type...I can't stay that they are intuitively obvious either!
I don't think it is worthwhile to "abolish the @-keywords" and start
unifying the existing language with C. Given the benefits Objective-C
already offers, I hope the group decides on improving it (in the
spirit that it was developed), rather that work towards a new
"unified language".
Its hard to believe a feature as simple as class variables has
spawned such a flurry of email.
Wait till we get to the hard stuff :-)
snaroff.
Begin forwarded message:
Date: Tue, 23 Feb 93 20:40:18 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: dudney@pencom.com
Cc: Steve_Naroff@NeXT.COM, gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302232307.AA01993@> (message from Bill Dudney on Tue,
23 Feb 93 17:07:53 GMT-0600)
Subject: Class Variables
It was a mistake to design the syntax of Objective C using the
special
keywords that start with @.
This made the language incoherent. It looks like two parts grafted
together--rather than like a natural whole. It could instead have
been done with C-like syntax, making a unified language.
This was a hasty job. It is not something to take as an inspiration.
**NOTE** This is a matter of syntax; it has nothing to do with the
semantic differences between Objective C and C++.
Return-Path:
Date: Wed, 24 Feb 93 13:54:26 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: Steve_Naroff@NeXT.COM
Cc: gnu-objc@gnu.ai.mit.edu, dudney@pencom.com, snaroff@NeXT.COM
In-Reply-To: <9302241833.AA04715@oz.NeXT.COM> (Steve_Naroff@NeXT.COM)
Subject: @-madness
It makes sense to make message features orthogonal to the features of
C. This does not imply they need be an "alien invasion" of C. That
is a fast and easy way of insuring orthogonality, but not the best
way.
It's possible to avoid the mistakes of C++, and write features with
the semantics of Objective C, using constructs which are both similar
in spirit to C syntax, and orthogonal to the existing C constructs.
I'm not saying we should redesign the syntax of Objective C now. That
would be a lot of work that isn't strictly necessary, and it's
unlikely Objective C users would switch even if they agreed it were
better.
Return-Path:
From: billb@jupiter.fnbc.com (Bill Burcham)
Date: Wed, 24 Feb 93 14:34:33 -0600
To: Steve_Naroff@next.com (Steve Naroff)
Subject: Re: Class Variables
Cc: GnuObjcProj@fnbc.com
I realize we need to get this thing out the door, but while everyone
is thinking about the class variable issue maybe we could make a stab
at fixing a problem (instead of arguing about another symptom).
I think that the real problem is that instances of class Class are
not treated the same as instances of instances of class Class. Now I
am not saying (yet) that we should go to a prototype/instance
language (where every object can essentially be a class object). I
just think that we could treat "class" objects in a way more akin to
the way we treat "instance" objects.
My suggestion is that we split Class stuff from instance stuff in our
source code.
-------Date.ch-------
#import
@interface DateClass:Class
{ id listOfAllDates;
}
- alloc; // Notice we don't need funky + anymore
// A bunch of Date class methods could go here
@end
-------Date.cm-------
#import "Date.ch"
@interface DateClass
{ id listOfAllDates;
}
// A bunch of DateClass methods could go here
@end
-------Date.ih-------
#import
@interface Date:Object
{ int julianDate;
}
- setStringValue:(const char*)str;
- (const char*)stringValue;
- addBusinessDays:(int)howmany; // etc...
@end
-------Date.im-------
#import "Date.ih"
@implementation Date
// A bunch of instance methods go here
@end
Notice:
1) DateClass is a subclass of Class and represents class state and
functionality for Dates.
2) We actually remove some syntax as there is no more need for `+'
methods.
3) I realize that there are some _big_ _holes_ in this proposal -- it
is not _fully_ thought out yet, but I wanted to get your ideas on it.
PS Since starting this post, I have read lots more stuff from the
list. In particular these ideas might meld with those expressed by
Kresten Krab Thorup :
> I am considering the possibility to introduce a class
> Class in objective C -- i.e. the class of class Objects,
> somewhat like it is known in Smalltalk.
---
+--------------------------------+----------------------------------+
| Bill Burcham | "Make no small plans; they have |
| First National Bank of Chicago | no magic to stir men's souls" |
| billb@fnbc.com (NeXTmail) | Daniel J. Burnham |
+--------------------------------+----------------------------------+
Return-Path:
From: Kenneth Lerman
X-Mailer: SCO System V Mail (version 3.2)
To: gnu-objc@gnu.ai.mit.edu, lupson@geom.umn.edu
Subject: Re: Class Variables
Date: Wed, 24 Feb 93 15:44:28 EST
I've suggested this before, but I'll try again:
@interface Foo : Object
{
// class variables go here
}
: // a delimeter of some type, could be @, or whatever
{
// instance variables go here
}
Has some advantages over other suggestions
1 -- class and instance variables are appropriately grouped
2 -- existing code need not be changed
3 -- does not add new MODES to the language (think about it):
@-
instanceVars
@+
classVars
Adds lexemes which cause the mode to be switched. IMHO, this
is as nasty in a language as it is in an editor.
The disadvantage of my suggestion is that the order of the two
sections is arbitrary, without a mnemonic way of knowing which section
comes first.
Another advantage (which I'm a little hesitant to mention) is that
I've already made this change to a version of Stepstone's Objective-C
compiler. But that won't (and shouldn't) sway the decision.
If it were up to me, I would also change the way @public fits into the
grammar works. As I've said, I really don't like modes.
How about:
@interface Foo : Object
@instanceVar { @public { // public iVars } // private iVars } @classVar { ...}
i.e. @public, @private, @instanceVar, @classVar indicate the beginning
of scopes delimited by {}. I don't consider that to be the same as a mode.
Ken
--
Kenneth Lerman ...!uunet!casey!gaboon!seltd!lerman
Systems Essentials Limited (203)426-4430
55 Main Street
Newtown, CT 06470
Return-Path:
Date: Wed, 24 Feb 93 22:11:29 +0100
From: Erick Herring
To: rms@gnu.ai.mit.edu (Richard Stallman)
Subject: Re: @-madness
Cc: Steve_Naroff@NeXT.COM, gnu-objc@gnu.ai.mit.edu, dudney@pencom.com
Reply-To: herring@pd.dth.dk
I think that it is worthwhile to note that, conceptually, the @-keywords are
delimiters. Using some form of an @-construction as a
type-modifier/storage-class seems to weaken the (again, conceptual)
cohesiveness of the source unit.
Without to regard to the usefulness of "static" as a class-variable
type-modifier/storage-class, I think that it would be useful to find an
unambiguous notational convenience for the declaration of class-variables.
Mr. Stallman is quite correct in pointing out that this is a syntactic issue,
and Mr. Naroff is quite correct in his assertion that there is nothing
particularly intuitive about the @-notation. I don't think that anyone will
argue that 'i++' is terribly intuitive, though there quite likely exists a
large portion of the readers of this list that would assert that it is
beautiful.
I guess that means that I agree with everyone :-)
As an obligatory statement of opinion, I would like to see something along the
lines of 'classvar id' or 'cvar id'. Even using + and - would be okay, though
I am not really very excited about "overloading" the meaning of existing
constructs.
If my 'classvar's end up looking like 'static's to the compiler, then that is
just peachy, but I come down on the side of notational convenience and
readability -- which includes readability for non-ObjC programmers (who, would,
I think, have a rough time with seeing static and having it mean something
wildly different than it means in normal C).
I'm out of breath, now, thanks for your attention.
Erick
---
-----
Erick Herring | Computation is the art of carefully throwing away
NeXT Systems Eng. | information [while] life is the art of carefully
Polyteknisk Data | throwing away opportunities, an interesting
(+45) 45 93 37 77 | coincidental parallel.
herring@pd.dth.dk | 1 Guy L. Steele Jr.
Return-Path:
Date: Wed, 24 Feb 93 15:05:59 -0600
From: jr@media.com (J.R. Jesson)
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: @-madness
Steve Naroff wrote:
>
> Its hard to believe a feature as simple as class variables has spawned
> such a flurry of email.
>
> Wait till we get to the hard stuff :-)
>
> snaroff.
>
Actually, I think we shouldn't get to the "hard" stuff until we get the
"simple" stuff down pat. I actually find it quite humbling to realize
that I've been coding around the lack of class variables for about a
year now, without even realizing it. Go ahead, make my code obsolete...
jr
---
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
J.R. Jesson
Chief Development Dude, All-Around Nice Guy, Wirehead
Multimedia Learning, Inc. (214)869-8282
jr@media.com. - Go Ahead, send NeXTMail!
Return-Path:
Date: Wed, 24 Feb 1993 21:29:36 -0500
To: gnu-objc@gnu.ai.mit.edu
From: bcox@gmuvax2.gmu.edu (Brad Cox)
X-Sender: bcox@gmuvax2 (Unverified)
Subject: Re: Class Variables
Cc: rs05@gte.com
>regarding Class vars, Linus Upson wrote:
>Nobody disputes that the @-stuff and the [obj: msg] stuff
>looks like an alien invasion of our beloved C homeland.
>
>But ... that's what it is SUPPOSED to be. Obj-C does not
>hide the fact that it is a layer on top of C. It does not
>pretend to be a stand-alone language; it is a simple graft
>of Smalltalk messaging syntax plus some class construction
>frobbery onto vanilla C structs. Inventing new keywords
>(or reusing old ones) to try and 'integrate' the two more
>closely will only serve to confuse matters.
Hear, hear! It was never my intention to design a completely new
programming language. It was to add the least that was needed to something
old and trusted to support a new level of software integration (i.e. a
larger unit of modularity than a subroutine; namely a Software-ICs).
Now that Objective-C is moving from its C substrate to a C++ substrate, its
more important than ever to keep the seams straight. Fabricate gate- and
block-level objects in the C++ level of the language. Assemble chip- and
higher-level objects in the Objective-C level of the language. Thus both
fabricate-from-scratch and assemble-from-prefab-components are possible
*within the same language*, but the two levels are syntactically distinct
(just as integration levels are distinct in silicon engineering).
--
Brad Cox; bcox@gmuvax2.gmu.edu; 703 993 1142 secy 703 968 8229 evenings
George Mason Program on Social and Organizational Learning; Fairfax VA 22030
--
Return-Path:
Date: Thu, 25 Feb 93 00:13:00 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: bcox@gmuvax2.gmu.edu
Cc: gnu-objc@gnu.ai.mit.edu, rs05@gte.com
In-Reply-To: <9302250224.AA25272@gmuvax2.gmu.edu> (bcox@gmuvax2.gmu.edu)
Subject: Class Variables
I see that you like the idea of having two levels,
but whether it is really a good idea is another question.
Return-Path:
Date: Wed, 24 Feb 93 21:38:51 MST
From: corybant!scott@rmnug.org (Scott Meyer)
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
> From: lupson@geom.umn.edu
> Rex Riley writes:
> > How much complexity for simplicity's sake? Will Gnu Obj-C join the C++
> > race for most powerful, expressive, and complex language?
Right on! If you want C++, you know where to find it...
> Class variables would seem to be a small, simple, and useful
> extension to the language. [...]
Small, simple, and useful extensions without some sort of plan
usually cause the system of which they are a part to become
large, complex and unusable.
> Currently this functionality is implemented with static
> variables, but that approach unfortunately complicates
> subclassing. It would seem to me that using static variables for
> class management makes the language more complex than using class
> variables.
How does this complicate subclassing? The difficulty that I assume
you are referring to is that subclasses cannot get at class variables
(really static variables) unless the superclass provides methods
to access the class variables. This may make you type more, but
it hardly qualifies as a significant increase in complexity.
Given that the vast majority of extant Objective C classes seem to
make do just fine without class variables, why penalize everyone by
adding a feature that benefits only a few? Certainly, I can ignore
features that I don't like, that's what I do when I use C++ :-)
> An alternate approach within the current language would be to make a
> single instance of a "class manager" object and use it (instead of the
> class object) to do bookkeeping. However, this is ugly.
Why is this ugly? Seems like pretty straightforward OO programming.
The case for class variables hasn't really been made in the discussion
so far. Most of the discussion seems to have centered around what sort of
syntax should be used to implement them.
I would much rather see a Smalltalk-style class/metaclass system
(really just an addition to the runtime) than an isolated "class
variable" feature (which might hamper later attempts to add
a class/metaclass system). Perhaps this is what whoever said "Why
deny the benefits of OOP to OOP?" was hinting at. If classes
were first-class objects, the class variables would just be ordinary
variables and there would be no need to have any special syntax at all.
-Scott
Return-Path:
From: Bill Shirley
Date: Wed, 24 Feb 93 17:37:58 -0600
To: GNUObjC@uunet.uu.net
Subject: Class variables
>
>
> The talk about class variables only being accessible by the class object
> indicates the distinction between (strictly) class variables, which only
> the class object sees, and class-instance variables, which the class
> object and all instances see. I think I heard somewhere that Smalltalk
> has both of these...? My personal preference would be to have just class-
> instance variables, rather just class-only variables. If we could manage
My preference would be the opposite, class-only variables.
If it's instances *need* to access them, it can provide methods to do so.
And I would prefer NOT to have both. That would just add some extra unnecesaries.
Heck, this might start looking like C+-.
> both flavors, I might like that, too (then again, I might start wondering
> if this OOP thing is really worth all the trouble ;-).
You should always doubt yourself, it's healthy. :-)
> rms@gnu.ai.mit.edu (Richard Stallman) writes (about the "@" keywords):
> >This made the language incoherent. It looks like two parts
> >grafted together--rather than like a natural whole. It
> >could instead have been done with C-like syntax, making a
> >unified language.
>
ssircar@canon.com replies...
SS > I disagree. As someone who knew C (and CLU) before learning Objective-C,
SS > the @ keywords were actually helpful; they told me what was going on. The
SS > keywords are clear and specify exactly what they mean, making reading and
SS > learning such code simpler and easier. I'm not sure what C-like syntax
SS > would meet this goal.
What I understood the rms quote to be sating is '@' looks grafted, and it probly
(initialy) was, the @ being a preprocessor flag to catch. I agree that looks like
two parts grafted together, but I think that is good. Subrata mentions that once
you know C (a natural previous state), the @s denote some of the differences that
you need to take note of.
The @keywords and [bracket notate:tions] should affront the C programmer, they
are the main step from non-OO to OO.
SS > In this particular case, I don't think "static" captures the idea of class
SS > variables quite correctly - I'd rather see @classVar and @instanceVar, or
SS > some variation thereof.
Steve Naroff adds...
SN > I don't think it is worthwhile to "abolish the @-keywords" and start
SN > unifying the existing language with C. Given the benefits Objective-C
SN > already offers, I hope the group decides on improving it (in the spirit that
SN > it was developed), rather that work towards a new "unified language".
agreed
Erick Herring adds...
EH > I think that it is worthwhile to note that, conceptually, the @-keywords
EH > are delimiters. Using some form of an @-construction as a
EH > type-modifier/storage-class seems to weaken the (again, conceptual)
EH > cohesiveness of the source unit.
Definately, this is why I didn't line @classVar, but I don't mind 'class id'.
I just couldn't figure out why it bothered me.
Since we're so @happy we could just make it
@id classVariable;
id instanceVariable;
no I don't like that either.
Kenneth Lerman says...
KL > @interface Foo : Object
KL > @instanceVar { @public { // public iVars } // private iVars } @classVar { ...}
KL >
KL > i.e. @public, @private, @instanceVar, @classVar indicate the beginning
KL > of scopes delimited by {}. I don't consider that to be the same as a mode.
I'd prefer to add as few keywords as possible, but not to skimp where they are needed.
I think this is a few too many, and a little more structure than needed.
(Our code might come out looking like X widgets ;-)
>
> --
> Nik Gervae
> Software Publications ## S2/8bg+-l+y++-/:!z-n-++o-+/++:x-+:a++:u-+v+:j+-p(eR)
> NeXT Computer, Inc. ## B2(go-t & sburns)f-t+c-!g-(--)k--s---mr-p+
> ngervae@next.com ## [[[[NXDisclaimer alloc] init] disclaim] free];
>
>
Return-Path:
Date: Thu, 25 Feb 93 08:13:15 -0700
From: Gary Frederick
To: bcox@gmuvax2.gmu.edu (Brad Cox)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
>Now that Objective-C is moving from its C substrate to a C++
>substrate, its more important than ever to keep the seams straight.
I would like to see some dialog on what Objective-C++ should be,
and how to get from where we are to where we need to be. Then
specifics can be thrashed out.
Gary
Return-Path:
Date: Thu, 25 Feb 93 10:26:50 -0600
From: burchard@geom.umn.edu
To: corybant!scott@rmnug.org (Scott Meyer)
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
corybant!scott@rmnug.org (Scott Meyer) writes:
> lupson@geom.umn.edu (Linus Upson) writes:
> > Currently this functionality is implemented with static
> > variables, but that approach unfortunately complicates
> > subclassing. It would seem to me that using static variables for
> > class management makes the language more complex than using class
> > variables.
>
> How does this complicate subclassing? The difficulty
> that I assume you are referring to is that subclasses
> cannot get at class variables (really static variables)
> unless the superclass provides methods to access the
> class variables. This may make you type more, but it
> hardly qualifies as a significant increase in
> complexity.
No, the difficulty is that with the use of static variables is that
subclasses get exactly the same *identical* variable. There is no
automatic way now for each subclass to transparently get access to a
distinct instantiation of the same conceptual variable.
For example, if a class needs to keep track of its instances, you
might try to define
@implementation BaseClass
static unsigned int instanceCount; // faked class variable
+ (unsigned int *)counter { return &instanceCount; }
But then subclasses will automatically inherit and modify BaseClass's
instance counter...ooops! Currently, in order to subclass this
behavior, each subclass would be required to define a new static
variable and to override the +counter method.
--------------------------------------------------------------------
Paul Burchard
>>>>>>>>> Global variables: the "GOTO" of the 90's <<<<<<<<<<<<<<<<
--------------------------------------------------------------------
Return-Path:
Date: Thu, 25 Feb 93 11:24:52 -0600
From: lupson@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: lupson@geom.umn.edu
Scott Meyer writes:
> Small, simple, and useful extensions without some sort of plan
> usually cause the system of which they are a part to become
> large, complex and unusable.
The idea behind adding class variables is to allow class objects to be
complete functional objects (with state) like all other objects in Obj-C.
If done properly (which is what we are working out now) class variables
will simplify the language -- we will go from the situation, "All objects
can have state except for class objects which do not except when hacked
with static variables" to the situation, "All objects can have state."
> How does this complicate subclassing? The difficulty that I assume
> you are referring to is that subclasses cannot get at class variables
> (really static variables) unless the superclass provides methods
> to access the class variables. This may make you type more, but
> it hardly qualifies as a significant increase in complexity.
If you were to get a hold of a static variable through a message to a
superclass (possibly indirectly) you would be getting the superclass'
class variable! If you wanted to properly subclass you would have to
redefine the variable in the subclass and make sure that you don't use any
of the inherited class methods that access the variable (which would not
know about the copy of the variable in the subclass, and instead would act
on the variable in the superclass). Static variables are bad here because
they add state to pieces of code, and not to "objects."
> > An alternate approach within the current language would be to make a
> > single instance of a "class manager" object and use it (instead of the
> > class object) to do bookkeeping. However, this is ugly.
>
> Why is this ugly? Seems like pretty straightforward OO programming.
It also has subclassing problems -- If you don't subclass both classes
(the actual class and its manager) you run into the same difficulty as
with statics. Also, even if you do subclass both of them, what is to
prevent the inherited class methods from using the superclass class
manager and not the subclass class manager? Same problem as before.
Nik Gervae writes:
> My personal preference would be to have just class-instance variables,
> rather just class-only variables. If we could manage both flavors, I
> might like that, too (then again, I might start wondering
> if this OOP thing is really worth all the trouble ;-)
You can always share class variables with all the instances of that class
by doing something like something like:
@interface MyClass:MySuperClass
{
+ id myClassId;
+ int myClassInt;
int *myInstanceIntPtr;
float myInstanceFloat;
}
+ (int *)revealClassInt;
- init;
@end
@implementation MyClass
+ (int *)revealClassInt
{
return &myClassInt;
}
- init
{
[super init];
myInstanceIntPtr = [[self class] revealClassInt];
return self;
}
@end
But if you have class-instance variables, you can't "put the genie back in
the bottle," and you're stuck with the encapsulation leakage.
Side note: Notice the [self class] in init. If MyClass is subclassed,
you want to get a pointer to the subclasses myClassInt, not a pointer
MyClass' int (maybe I should have picked different variable names :-).
Second side note: Notice the plug for the "+/-" class variable declaration
syntax. In declaring methods, a "+" means a method only for the class
object, and "-" means a method only for the instances of the class. Since
class variables should only be accessible through the class object, and
instance variables only accessible through instances of the class, the
"+/-" notation for variables is consistent, clear, concise, and non-modal.
Linus Upson
The Geometry Center
lupson@geom.umn.edu
P.S. I hope I didn't misquote anyone. In a previous message I transposed
Bill Shirley and Bill Burcham, and I noticed that Brad Cox put my name in
front of something I didn't write (although I wish I had). I can see
flipping Bill & Bill, but how can you get confused about a Linus? :-)
Return-Path:
Date: Thu, 25 Feb 93 04:21:54 -0500
From: athan@object.com (Andrew Athan)
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables -- be careful!
4 sections:
(1)----------SOMETHING TO AVOID----------------------------------
Some notes on existing implementations of ObjC (back compatibility
issues): Ivars are visible in class methods. This is what allows me
to do the following (this implies self in the context of the class
object IS a instance struct):
+ new
{
self = [Object getMemory];
ivarFoo = 10;
ivarBar = 20;
return self;
}
Whatever syntax & semantics are used to reference cvars must not break
this.
Thus, the class object IS an instance object. It just has different
dispatch tables and points to a different superclass--all class objects
have Object as their superclass. The "isa" ivar jacks you into the
meta class structs where all this stuff is stored.
(2)----------MAYBE, SOMETHING NOT TO AVOID-------------------
Class variables can be implemented in a variety of ways through the use
of the existing meta class structs and even existing language
semantics.
E.g.1, the structs themselves can store the ivars & can be put into a
heirarchy exactly like class instances work (this is moving towards
implementation of a meta class system). Your isa when you are a class
points to a "fat" struct (i.e., with data possibly appended to it).
Your isa when you are an instance can point to either a thin (no cvars)
or a fat struct (see THUS:...)
E.g.2, add one ptr to the Class struct to hold a reference to the class
data. The Class struct stays the same no matter what class you are.
The cVarsPtr is nil for the isa of an instance. It takes one extra
memory reference to get to cvar data.
THUS: Both E.g.1 and E.g.2 both allow the syntax of cvar access to be
exactly like ivar access. The semantic, however, is to stick an
"isa->" in front of the variable name before applying the regular ivar
semantics (e.g., cvarFoo=10; becomes self->isa->cvarFoo=10; instead of
self->cvarFoo=10;). Ivar and Cvar access is therefore syntactically
and, strictly speaking, semantically correct everywhere (thus
maintaining the low-level equivalence of + and - methods). Running the
code in an instance method, however, gives undefined results if isa
points to a thin struct. If it points to a fat struct, we have come
full circle cvars look to instances like ivars look to classes.
(3)----------IN ANSWER TO A POST-------------------
Scott Meyer writes:
> > Currently this functionality is implemented with static
> > variables, but that approach unfortunately complicates
> > subclassing. It would seem to me that using static variables for
> > class management makes the language more complex than using class
> > variables.
>
> How does this complicate subclassing? The difficulty that I assume
> you are referring to is that subclasses cannot get at class variables
> (really static variables) unless the superclass provides methods
> to access the class variables. This may make you type more, but
> it hardly qualifies as a significant increase in complexity.
>
The one major semantic difference you have forgotten is that, like an
instance gets its own copies of ivars, a subclass gets its own copies
of class variables. So, the class variable "initCount" (which,say, is
incremented in the designated initializer of a class?) declared in
class A and referenced in the context of class A has a value. That
same variable referenced in the context of class B (A's subclass) has a
different value.
(4)----------A REMINDER ABOUT objc-runtime-------------------
There is a special list, gnu-objc-runtime for the discussion of
detailed issues pertaining to the implementation of the runtime support
system. Volume on gnu-objc has been light, so it's probably ok to send
everything to everyone. However, I urge you to keep the 4 special
purpose lists in mind and to start taking discussions there as you see
fit. Subscription requests to
gnu-objc-runtime-request@prep.ai.mit.edu
gnu-objc-map-request@prep.ai.mit.edu
gnu-objc-ibex-request@prep.ai.mit.edu
gnu-objc-coop-request@prep.ai.mit.edu
Date: Thu, 25 Feb 93 12:54:06 -0600
From: burchard@geom.umn.edu
To: athan@object.com (Andrew Athan)
Subject: Re: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
athan@object.com (Andrew Athan) writes:
> (1)----------SOMETHING TO AVOID----------------------------------
...
> + new
> {
> self = [Object getMemory];
> ivarFoo = 10;
> ivarBar = 20;
> return self;
> }
Most definitely...it makes my stomach turn to even look at it...
> Whatever syntax & semantics are used to reference cvars
> must not break this.
??? I hope that no one has ever written any code that uses this horrible hack/loophole. And if they have, the sooner such programs are exposed, the better, IMHO.
Lesson: like the Sunday school teacher said, do not play with your self.
--------------------------------------------------------------------
Paul Burchard
********** Global variables: the ``GOTO'' of the 90's **********
--------------------------------------------------------------------
From: Steve_Naroff@NeXT.COM (Steve Naroff)
Date: Thu, 25 Feb 93 11:03:08 -0800
To: athan@object.com (Andrew Athan)
Subject: Re: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
Andrew writes:
(1)----------SOMETHING TO AVOID----------------------------------
Some notes on existing implementations of ObjC (back compatibility issues): Ivars are visible in class methods.
<< example >>
Whatever syntax & semantics are used to reference cvars must not break this.
snaroff:
We would really like to change this. Allowing instance variables to be accessed from class methods is EXTREMELY ERROR PRONE. I have been pulled into many debug situation where someone does:
+ new
{
if (someCondition)
self = [Object getMemory];
ivarFoo = 10;
ivarBar = 20;
return self;
}
If "someCondition" isn't true, self is not initialized and the class data structures in the Objective-C runtime are overwritten...causing things to break pretty quickly! Ever since allocation and initialization have been separated, this practice is much less common (within NeXT at least). Nevertheless, it should be disallowed by the language.
snaroff.
To: lupson@geom.umn.edu
Cc: gnu-objc@gnu.ai.mit.edu, rs05@gte.com
Subject: Re: Class Variables
In-Reply-To: Your message of "Thu, 25 Feb 93 11:24:52 CST."
<9302251724.AA00890@minkowski.geom.umn.edu>
Date: Thu, 25 Feb 93 13:57:20 -0500
From: rs05@gte.com
X-Mts: smtp
[Linus Upson (lupson@geom.umn.edu) suggests a way to
add class vars to the language, while hiding them
from instances except through class methods]
I think this is a rational approach.
It would be 'convenient' to have direct access to
those variables, but I agree with Linus that to do
so would lead to subclasses that are too dependent
on the superclass implementation.
also, I think his suggested syntax (below) reads well,
is quite succinct, is unambiguous, and is consistent with
the class/instance method designation scheme already
in place. beautiful it ain't, but it fits in very well.
--Russ
rs05@gte.com
> You can always share class variables with all the instances of that class
> by doing something like something like:
>
> @interface MyClass:MySuperClass
> {
> + id myClassId;
> + int myClassInt;
> int *myInstanceIntPtr;
> float myInstanceFloat;
> }
> + (int *)revealClassInt;
> - init;
> @end
>
> @implementation MyClass
> + (int *)revealClassInt
> {
> return &myClassInt;
> }
> - init
> {
> [super init];
> myInstanceIntPtr = [[self class] revealClassInt];
> return self;
> }
> @end
>
> But if you have class-instance variables, you can't "put the genie back in
> the bottle," and you're stuck with the encapsulation leakage.
Date: Thu, 25 Feb 93 15:09:06 CST
From: peter@tahiti.umhc.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
> [Linus Upson (lupson@geom.umn.edu) suggests a way to
> add class vars to the language, while hiding them
> from instances except through class methods]
> I think this is a rational approach.
ditto.
> ...
> also, I think his suggested syntax (below) reads well,
> is quite succinct, is unambiguous, and is consistent with
> the class/instance method designation scheme already
> in place. beautiful it ain't, but it fits in very well.
I agree, but... If we agree that cvars shouldn't be directly accessed by anyone besides that class, why should any other classes even know they exist other than the methods provided to read/change them? Cvars have no place in an interface file. They should be declared and used in the implementation file(s) for that class. How are they delimited? I don't know. The +/- would make sense if cvars and ivars had to be side by side, but if they will ALWAYS be in separate file(s) or atleast separate sections of code that may be enough.
ie.
@interface Foo:Object
{
// ivars
}
//cmethods
//imethods
@end
@implementation Foo
(?)
// cvars
(?)
//cmethods
//imethods
@end
where some person smarter than I would replace the '(?)' with an appropriate symbol. I like the '{'s but I know that this confilcts with published documents.... (Maybe I've been breaking rules on a NeXT for too long now...)
peter
peter@tahiti.umhc.umn.edu (Peter Eisch)
dig.
Date: Thu, 25 Feb 93 20:23:51 +0100
From: Peter Rasmussen
To: gnu-objc@prep.ai.mit.edu
Subject: Re: Class Variables
Reply-To: rasmus@dannug.dk
In article ??? burchard@geom.umn.edu writes:
Hi ..
Concerning the desire to separate the definition of class and instance variables.
> We already define instance and class _methods_ in the same place, but
> use (+) and (-) to distinguish them. Why not do the same with
> instance and class variables (i.e., variables visible within the
> scope of instance and class methods, respectively)?
>
> @interface MyClass
> {
> @-
> // variables visible within instance methods
> id anInstanceVariable;
> @+
> // variables visible within class methods
> id aClassVariable;
> }
>
To me this depends upon how the concept of how class variables is defined.
1)
As I understand Objective-C class variables are not REALLY supported in the object system. Rather they are ordinary C-language variables layed out in global scope within the .o module of a class.
- To hold them encapsulated I do also define them
*static* like Stallman suggested.
- Since they as C-variables are outside of the ObjC object
system do NOT get inherited - I see no reason to declare
them in the class @interface.
1) They should not be accessed directly by users of class
2) Neither by subclass implementors
3) So why put their declaration into the @interface def.
2)
If class variables were to be introduced into the GNU Objective-C system object system, then things would be different. Then they would be inherited by subclasses and th
eir definition would be relevant to place into the @interface def.
Regards
Peter Rasmussen
PS: Sorry if this got posted twice ...
--------------------------------------------------------------------
Peter Rasmussen : Aalborg University (AUC).
: Department of Computer Science.
rasmus@dannug.dk (NeXTmail ok) : 9000 Aalborg, DK-Denmark.
Tel/(Fax): +45 98 145456 : Office. (+45) 98 154211 # 5000
--------------------------------------------------------------------
Date: Thu, 25 Feb 93 15:41:02 -0600
From: lupson@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: lupson@geom.umn.edu
Peter Eisch writes:
> If we agree that cvars shouldn't be directly accessed by anyone besides
> that class, why should any other classes even know they exist other than
> the methods provided to read/change them? Cvars have no place in an
> interface file. They should be declared and used in the implementation
> file(s) for that class.
Inheritance. Class variables need to be declared in the interface file for the same reason that instance variables need to be declared there -- subclasses need to know what they inherit from their parents. That way you can subclass somebody else's object without having the source.
Linus Upson
The Geometry Center
lupson@geom.umn.edu
From: Kenneth Lerman
X-Mailer: SCO System V Mail (version 3.2)
To: burchard@geom.umn.edu, corybant!scott@rmnug.org
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Date: Thu, 25 Feb 93 15:49:50 EST
Paul Burchard writes:
No, the difficulty is that with the use of static variables is that
subclasses get exactly the same *identical* variable. There is no
automatic way now for each subclass to transparently get access to a
distinct instantiation of the same conceptual variable.
For example, if a class needs to keep track of its instances, you
might try to define
@implementation BaseClass
static unsigned int instanceCount; // faked class variable
+ (unsigned int *)counter { return &instanceCount; }
But then subclasses will automatically inherit and modify BaseClass's
instance counter...ooops! Currently, in order to subclass this
behavior, each subclass would be required to define a new static
variable and to override the +counter method.
---------end of quote-------
What I've done to get "class variable" like behavior using statics is
something like:
SomeClass.h:
@interface SomeClass : Object
{}
#define CV_SomeClass static int instanceCount; \
+ (int)getInstCnt { return instanceCount; } \
+ putInstCnt:(int)cnt { instanceCount = cnt; return self; } \
+ bumpInstCnt { instanceCount++; return self; } \
- (int)getInstCnt { return instanceCount; } \
- putInstCnt:(int)cnt { instanceCount = cnt; return self; } \
- bumpInstCnt { instanceCount++; return self; } \
...
// assorted other stuff
@end
Then in any class which I want to have these "class variables":
aClass.m:
#import "SomeClass.h"
CV_SomeClass
...
//Whatever else you need
Note that I've chosen to make "class variables" accessible from both
classes and instances.
Ken
--
Kenneth Lerman ...!uunet!casey!gaboon!seltd!lerman
Systems Essentials Limited (203)426-4430
55 Main Street
Newtown, CT 06470
Date: Thu, 25 Feb 1993 17:18:54 -0500
To: gnu-objc@gnu.ai.mit.edu
From: bcox@gmuvax2.gmu.edu (Brad Cox)
Subject: Re: Class Variables
Cc: lupson@geom.umn.edu
lupson@geom.umn.edu wrote
>P.S. I hope I didn't misquote anyone. In a previous message I transposed
>Bill Shirley and Bill Burcham, and I noticed that Brad Cox put my name in
>front of something I didn't write (although I wish I had). I can see
>flipping Bill & Bill, but how can you get confused about a Linus? :-)
Whups! Sorry about that. Am using Eudora which makes quoting the
responsibility of the human, not the machine. In other words, I blew it.
Sorry about that.
--
Brad Cox; bcox@gmuvax2.gmu.edu; 703 993 1142 secy 703 968 8229 evenings
George Mason Program on Social and Organizational Learning; Fairfax VA 22030
--
From: Steve_Naroff@NeXT.COM (Steve Naroff)
Date: Thu, 25 Feb 93 12:53:58 -0800
To: Kresten Krab Thorup
Subject: Re: Optimizing the GNU objc runtime [long]
Cc: gnu-objc@gnu.ai.mit.edu
Here is some data for a "typical" application on a NeXT (linked with the standard shared library of objects that we supply):
200-300 classes
6000-7000 method implementations
2000-3000 selectors (unique method names)
Many of these are classes are "private"...nevertheless, it is important that the runtime scale to support a system of this magnitude. It seems like you have already abandoned the idea of a per-class vector that has room for all possible selectors. This is good, since my "back of the envelope" calculation comes out to 3.2 megabytes to store all the caches (using 200 classes, 2000 selectors in the computation)! Let me know if I misinterpreted your proposal.
It sounds like the sparse array idea might reclaim much of this overhead. I would be interested in how much space that works out to be. The NeXT runtime typically consumes between 20-40 kilobytes for the per-class caches. The space occupied is proportional to the classes/methods used by the application. The simple rule is "pay if you play". In fact, even though there are 200-300 classes linked into an application, only 30-50% are typically used. I think any scalable system must incur mininal overhead (on a per-class basis) until the class is actually used.
Another method for doing dynamic dispatch (that is similar in spirit to your scheme) is to have a vector that is maintained on a per-app basis (not per-class) that has an entry for each selector. Each entry would contain a chain of classes that implement the selector...in practice, this chain is very short. A simple way to view this is go from the selector->class, rather than class->selector. I'm not convinced it statisfies your performance goals, but it is another way to look at the problem.
I think it is worthwhile goal to improve the performance of dispatching messages in Objective-C. Just be aware that it is a classic "time vs. space" problem...and saving time without carefully considering space doesn't work. Most computers are getting a lot faster without adding significantly more memory...this should influence the tradeoffs we make when designing the new runtime (my perspective, of course).
In the past, we have spent time optimizing memory utilization and improving locality of reference. This includes the data generated by the compiler as well as caches that are dynamically allocated (which are often "hot" for commonly used classes). We also developed a program called "objcopt" that improves launch time by building the selector hash table and "freeze drying" it in the executable for each shared library that we ship.
Given the portability goals of the project, I can't say that many of these apply to the GNU runtime...I just wanted to let you know what problems we work on wrt optimizing the NeXT Objective-C runtime.
btw...the NeXT runtime sends the "+initialize" lazily, was the change to execute before main() made intentionally?
regards,
snaroff.
Date: Thu, 25 Feb 93 18:04:54 -0500
From: rms@gnu.ai.mit.edu (Richard Stallman)
To: Steve_Naroff@NeXT.COM
Cc: krab@iesd.auc.dk, gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302252054.AA20409@oz.NeXT.COM> (Steve_Naroff@NeXT.COM)
Subject: Optimizing the GNU objc runtime [long]
In fact, even though there are 200-300 classes linked into
an application, only 30-50% are typically used. I think any scalable
system must incur mininal overhead (on a per-class basis) until the
class is actually used.
It ought to be possible to delay setting up a class's method dispatch
table until the first time it is instantiated. Until then you need
only the dispatch mechanism for the methods that act on the class
rather than on an instance. I expect there will be much fewer
operations of that sort.
Date: Fri, 26 Feb 1993 00:53:14 +0100
From: Kresten Krab Thorup
To: Steve_Naroff@NeXT.COM (Steve Naroff)
Cc: Kresten Krab Thorup , gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302252054.AA20409@oz.NeXT.COM>
Subject: Re: Optimizing the GNU objc runtime [long]
Steve Naroff writes:
> It seems like you have already abandoned the idea of a
>per-class vector that has room for all possible selectors. This is
>good, since my "back of the envelope" calculation comes out to 3.2
>megabytes to store all the caches (using 200 classes, 2000 selectors
>in the computation)! Let me know if I misinterpreted your proposal.
You're right. Obviously we cannot have an array with domaine of all
selectors for each class. I have been in this belief for some time
now. The comments in the `Optimizing ...' article were to make it
clear that this was not the subject of the paper.
>It sounds like the sparse array idea might reclaim much of this
>overhead. I would be interested in how much space that works out to
>be.
I have a prototype of the runtime up running using sparse arrays for
dispatch. Ok, I compiled the first program successfull 10 minutes
ago, so I'll have to test it a bit more before it's worth distributing!
>The NeXT runtime typically consumes between 20-40 kilobytes for
>the per-class caches. The space occupied is proportional to the
>classes/methods used by the application. The simple rule is "pay if
>you play". In fact, even though there are 200-300 classes linked into
>an application, only 30-50% are typically used. I think any scalable
>system must incur mininal overhead (on a per-class basis) until the
>class is actually used.
This mechanism could be adopted to install the tables incrementally,
if only we had objc_msgSendv!!! Please, if someone is into assember
and gcc internals do it! I dont know far enough about assember to do
it, who could we possibly ask?
I am very excited to see some performace result from my new runtime.
Sadly enough I will be gone for the weekend :-)
I myself is actually very fond of using caches and ordinary dynamic
lookup. This has one big advantage which my scheme will have to pay
for: It is simple to add methods to excisting classes at runtime. On
the other hand, by installing magic handlers in the dispatch table, my
scheme allows the programmer to install his own messenger on class
basis. I guess to think of a nice API for this ..
>Given the portability goals of the project, I can't say that many of
>these apply to the GNU runtime...I just wanted to let you know what
>problems we work on wrt optimizing the NeXT Objective-C runtime.
I dont know for sure. I guess most things written in GNU objc will
probably NOT be large applications with zillions of classes and using
dynamic loading. At least it will take some time before this will be
the case, since class libraries and loading stuff is not easily
accessible... Several operating systems provide facilities -- I know,
but far from all.
>btw...the NeXT runtime sends the "+initialize" lazily, was the change
>to execute before main() made intentionally?
Initially, yes. The problem is that if you access variables
initialized in "+initialize" directly (without a message call) you are
not sure about the state of these. After having talked to some fellow
students, I may have changed my mind, but one must enforce the
constraint that such variables may only be accessed through method
invocations. It may be a problem, if class variables are introduced,
that you can say MyClass->aVariable, but aVariable is assigned its
default value in "+initialize" !
I hope to be able to release a beta version of my new runtime within a
week or so. It may be that someone are interested in studying it? :-)
/Kresten
Date: Fri, 26 Feb 1993 01:21:01 +0100
From: Kresten Krab Thorup
To: rms@gnu.ai.mit.edu (Richard Stallman)
Cc: Steve_Naroff@NeXT.COM, krab@iesd.auc.dk, gnu-objc@gnu.ai.mit.edu
In-Reply-To: <9302252304.AA06929@mole.gnu.ai.mit.edu>
Subject: Optimizing the GNU objc runtime [long]
Richard Stallman writes:
>It ought to be possible to delay setting up a class's method dispatch
>table until the first time it is instantiated. Until then you need
>only the dispatch mechanism for the methods that act on the class
>rather than on an instance. I expect there will be much fewer
>operations of that sort.
This is easily done using the sparse array scheme. To do it, we would
initially install a dispatch table where the empty bucket is filled
with some function which installs the right dispatch table and forwards
the message. We will however need the ability to do forwarding.
Do you think we can find someone who'd like to implement a forwarding
primitive? At least the primitive one (__builtin_forward) we've been
talking about which does not allow one to do anything after the
forward. Using this we could implement the lazy dispatch table setup,
as well as lazy initialization.
/Kresten
Date: Thu, 25 Feb 93 23:37:06 -0800
From: John Jay Feiler
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: relief!jjfeiler@uu2.psi.com
I think that the introduction of class variables into Obj-C is something that should definitely, be done, and I personally favor the @classVariable idea. However, there are ways to get around the lack of class variables in Obj-C. Here's what I do:
Say I want to have an object of type Foo associated with each class that inherits from class A
@interface A:Object
+ initialize;
+ (Foo *)foo;
+ setFoo:(Foo *)aFoo;
@end
@implementation A
static HashTable *fooHT;
+ initialize
{
fooHT = [[HashTable alloc] initKeyDesc:"@" valueDesc:"@"];
return self;
}
+ (Foo *)foo
{
Foo *aFoo;
if([fooHT isKey:self])
{
aFoo = [fooHT valueForKey:self];
}
else
{
aFoo = [[Foo alloc] init];
[self setFoo:aFoo];
}
return aFoo;
}
+ setFoo:(Foo *)aFoo
{
[[fooHT insertValue:aFoo key:self] free];
return self;
}
The HashTable fooHT is static, and only within the scope of the original Class A factory object, but since class methods are inherited, any subclass of A will call the +setFoo: and +getFoo methods above, and each factory object will have its own foo object associated with it.
Is it pretty? No. Does it work? Yes. At least until we get class variables implemented, anybody who really needs them can "fake" them.
Just my $0.02
John
Date: Thu, 25 Feb 93 23:52:34 -0800
From: John Jay Feiler
To: Steve_Naroff@NeXT.COM (Steve Naroff)
Subject: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
Reply-To: relief!jjfeiler@uu2.psi.com
If we don't allow a class method to access instance vars (or reassign self) how should we design objects which only have one instance, such as OpenPanel? I usually do the following:
@implementation Foo
static Foo *theFoo;
+ new
{
if(theFoo == nil)
{
self = theFoo = [super new];
/* initialize the Foo instance vars */
}
return self;
}
@end
This allows me to access the single object of class Foo with a simple message: [Foo new]
Faking this stuff with an alloc/init pair isn't very clean, and there is certainly use for Classes which only have one instance.
John
>
>
> Andrew writes:
>
> (1)----------SOMETHING TO
> AVOID---------------------------------- Some notes on
> existing implementations of ObjC (back compatibility
> issues): Ivars are visible in class methods.
>
> << example >>
>
> Whatever syntax & semantics are used to reference cvars
> must not break this.
>
> snaroff:
>
> We would really like to change this. Allowing instance
> variables to be accessed from class methods is EXTREMELY
> ERROR PRONE. I have been pulled into many debug situation
> where someone does:
>
> + new {
> if (someCondition)
> self = [Object getMemory];
>
> ivarFoo = 10; ivarBar = 20; return self; }
>
> If "someCondition" isn't true, self is not initialized
> and the class data structures in the Objective-C runtime
> are overwritten...causing things to break pretty quickly!
> Ever since allocation and initialization have been
> separated, this practice is much less common (within NeXT
> at least). Nevertheless, it should be disallowed by the
> language.
>
> snaroff.
>
From: billb@jupiter.fnbc.com (Bill Burcham)
Date: Fri, 26 Feb 93 09:40:44 -0600
To: lupson@geom.umn.edu
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Linus Upson writes:
> Peter Eisch writes:
> > If we agree that cvars shouldn't be directly accessed by anyone besides
> > that class, why should any other classes even know they exist other than
> > the methods provided to read/change them? Cvars have no place in an
> > interface file. They should be declared and used in the implementation
> > file(s) for that class.
>
> Inheritance. Class variables need to be declared in the
> interface file for the same reason that instance
> variables need to be declared there -- subclasses need to
> know what they inherit from their parents. That way you
> can subclass somebody else's object without having the
> source.
>
> Linus Upson
> The Geometry Center
> lupson@geom.umn.edu
Please feel free to FLAME ME WITH IMPUNITY, but this illustrates the fact that it is _wrong_ to have only one interface file per class. There is _no_ reason to have _any_ instance variable definitions in an interface file -- other than for subclassing purposes. The language would be better if we had seperate files for the subclassing interface vs. "use" interface. To avoid duplication, we could #import the "use" interface into the subclassing interface. NeXT made the situation a _little_ better by providing the @class stuff so I don't have to #import irrelevant class interface files, but think about it: there is no such mechanism for forward declaration of protocols! So, if I want to associate a protocol with one of my ivars (o.k. GNU doesn't have protocols _yet_, but bear with me) then I have to #import that protocol definition -- even though the user of this class DOESN'T HAVE ANY NEED TO HAVE THAT PROTOCOL IN ITS SCOPE.
If we did this then a "use" interface would start to look suspiciously like (simply) a protocol. The only thing we would have to add to a protocol would be some way to get the compiler to see the external declaration of the Class. All of the stuff that we are currently putting in our interface would go into the subclassing interface.
---
+--------------------------------+----------------------------------+
| Bill Burcham | "Make no small plans; they have |
| First National Bank of Chicago | no magic to stir men's souls" |
| billb@fnbc.com (NeXTmail) | Daniel J. Burnham |
+--------------------------------+----------------------------------+
Date: Fri, 26 Feb 93 10:25:35 -0600
From: burchard@geom.umn.edu
To: relief!jjfeiler@uu2.psi.com
Subject: Re: Class Variables -- be careful!
Cc: Steve_Naroff@NeXT.COM (Steve Naroff), gnu-objc@gnu.ai.mit.edu
> If we don't allow a class method to access instance vars
> (or reassign self) how should we design objects which
> only have one instance, such as OpenPanel? I usually do
> the following:
If you *must* do it this way, you can always say what you really mean, and display how you are directly accessing another object's ivars:
static Foo *theFoo;
+ new
{
if(theFoo == nil)
{
theFoo = [super new]; //!! relying on super to really alloc
theFoo->glub = 10; //!! directly accessing object's ivars
}
return theFoo;
}
Preferably, though, you would use the protocol that already exists. This will also subclass nicely:
static Foo *theFoo;
+ new
{
if(!theFoo) theFoo = [[self alloc] init];
return theFoo;
}
- init
{
if(![super init]) return nil;
glub = 10;
return self;
}
--------------------------------------------------------------------
Paul Burchard
********** Global variables: the ``GOTO'' of the 90's **********
--------------------------------------------------------------------
Date: Fri, 26 Feb 93 16:29:03 +0100
From: Peter Rasmussen
To: gnu-objc@prep.ai.mit.edu
Subject: Re: Class Variables
Reply-To: rasmus@dannug.dk
Hi, (sorry If you get this twice - I had a Mail reject)
I'm not convinsed that class variables must be supported by the ObjC runtime system.
You seem to seek ENCAPSULATION and INNHERITANCE of class variables by adding language concepts for class variables.
In fact we have both already: by the static solution.
1) Encapsulation.
As static C-variables they are only visible within the class .o module. This protects class variables from other classes giving encapsulation between metaclass/metaclass and between class/metaclass. But with one convenient exception.
ObjC runs an IMPLICIT parallel metahierarchy of "Metaclasses" which enables the lower encapsulation shelters between class/metaclass PAIRS. The implicit metaclasses are only supposed to a have a single instance anyway (the class object) so why bother wrapping them into real objects and pay by raising real shelters between class/metaclass PAIRS.
>From the class side: The benefit of static vars for class variables is that you also can access them directly from instance methods (of the same class only) - not just class methods. If there were real class variables then instance methods would have to message to class objects to get the class variables.
>From the metaclass side: Not that much to gain from lower class/metaclass pair barriers.
2) Inheritance.
Here is my main point. Inheritance of class variables does infact already exist with the static solution.
> Currently, in order to subclass this behavior, each
> subclass would be required to define a new static
> variable and to override the +counter method.
>
> #define CV_SomeClass static int instanceCount; \ +
> (int)getInstCnt { return instanceCount; } \ +
> putInstCnt:(int)cnt { instanceCount = cnt; return
> self; } \ + bumpInstCnt { instanceCount++; return
> self; } \
No - it is not necesseary to put NEW static class variables into each subclass. (I saw Kenneth use macro'es to make this easier). With this usage static becomes a bad and redundant solution - I agree.
Instead setup a subclass implementors interface for the static class variables. This means giving class methods to make them accessible. These class methods automatically gets inherited by your new IMPLICIT metaclass. And it is the subclass implementors responsibility to respect your subclass interface !!!
Let me give a simple example:
------------------------ BaseClass --------------
static int count; // the class variable
@implementation BaseClass:Object
{
}
+ initialize { count = 5; return self; }
+ (int)getCount { return count; }
+ setCount:(int)i { count = i; return self; }
@end
------------------------ ClassA --------------
@implementation ClassA:BaseClass
{
}
+ hereAmI { return self; }
@end
------------------------ Usage --------------
printf("Initialized %d\n, [BaseClass getCount]);
[ClassA setCount:10];
printf("New count %d\n", [ClassA getCount]);
------------------------ Execution --------------
Initialized 5
New count 10
So what is it that you seek by introducing class variables besides what can be achieved by static. OK - I need to set up class methods to access the STATIC class variables. But you would have to do that any way when wrapping the class variables into class-objects (from which there only exist a single anyway)
Regards
Peter Rasmussen
--------------------------------------------------------------------
Peter Rasmussen : Aalborg University (AUC).
: Department of Computer Science.
rasmus@dannug.dk (NeXTmail ok) : 9000 Aalborg, DK-Denmark.
Tel/(Fax): +45 98 145456 : Office. (+45) 98 154211 # 5000
--------------------------------------------------------------------
Date: Fri, 26 Feb 93 11:32:17 -0600
From: burchard@geom.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables -- be careful!
Cc: relief!jjfeiler@uu2.psi.com, Steve_Naroff@NeXT.COM (Steve Naroff),
gnu-objc@gnu.ai.mit.edu
I wrote:
> Preferably, though, you would use the protocol that
> already exists. This will also subclass nicely:
>
> static Foo *theFoo;
> + new
> {
> if(!theFoo) theFoo = [[self alloc] init];
> return theFoo;
> }
> - init
> {
> if(![super init]) return nil;
> glub = 10;
> return self;
> }
>
(I should have said, this will subclass nicely modulo the ever-present class variable problem. To really subclass this without class variables, we must in addition use John's trick and replace references to theFoo with class methods which retrieve the correct "class var" from a static HashTable that maps classes -> "class var" pointers. Sorry for any confusion.)
--------------------------------------------------------------------
Paul Burchard
********** Global variables: the ``GOTO'' of the 90's **********
--------------------------------------------------------------------
Date: Fri, 26 Feb 93 20:12:14 +0100
From: Peter Rasmussen
To: gnu-objc@prep.ai.mit.edu
Subject: Re: Class Variables
Reply-To: rasmus@dannug.dk
Paul Burchard wrote:
> > printf("Initialized %d\n, [BaseClass getCount]);
> > > [ClassA setCount:10]; > printf("New count %d\n",
> [ClassA getCount]);
>
> Your code does NOT implement "class variables"....it
> will give an incorrect answer for the next call to
> [BaseClass getCount]. The call to [ClassA setCount:10]
> has the "side effect" of also changing [BaseClass
> getCount].
Sure it does. This "side effect" was the whole intension. That ALL objects being kindOf BaseClass are able to share some non-redundant state.
This is "class variables" seen from the User Objects point of view
Holding User domain information.
> This is because there is no class variable inheritance
> here (inheritance of class *methods*, yes, of class
> *variables*, no). If "count" is a class variable
> that means I want to count each class separately.
I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
Lets take Kenneths example classes housekeeping how many instances they have. Sure this task would take a counting variable for each class. Separated yes - but why isolated ? Update of these "class variables" for counting ought to propagate within class methods.
If I instantiate eg. a View, I have also put one more object of all of its superclasses into play. So their instance counts should be updated also ...
static int count;
@implementation BaseClass:Object
{
}
+ initialize
{ count = 0; return self; }
+ (int)getCount
{ return count; }
+ bumpInstCnt
{ count++; return self; }
@end
------------------------------
static int count;
@implementation ClassA:BaseClass
{
}
+ bumpInstCnt
{ count++; return [super bumpInstCnt]; }
@end
And yes in this class object domain pt. of view it should be remembered to replicate class variables.
/Peter
From: Peter Eisch
Date: Fri, 26 Feb 93 15:13:55 -0600
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
Peter Rasmussen wrote:
>
> Paul Burchard wrote:
> > This is because there is no class variable inheritance
> > here (inheritance of class *methods*, yes, of class
> > *variables*, no). If "count" is a class variable
> > that means I want to count each class separately.
>
> I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
>
Put simply, the SCOPE of "Class Variables" should only be the class in which they are declared. They should not be visible to subclasses though the methods that manipulate them (if necessary) would be provided.
peter
peter@tahiti.umhc.umn.edu (Peter Eisch)
dig.
Date: Fri, 26 Feb 93 19:28:50 -0500
From: athan@object.com (Andrew Athan)
To: gnu-objc@prep.ai.mit.edu
Subject: Another interesting point (static)
A new user of Obj-C once was surprised by the following:
@implementation Foobar
- aMethod
{
static int x=10;
x=20;
}
@end
The guy had two instances of Foobar, and called aMethod on each. He was surprised to find that x==20 on entry into the second instance's call.
"Oh!" he said. "x is static in the same sense as in a static var in a function. I was expecting each instance to have a local static copy."
"... like an ivar, you mean?" someone replied.
Andrew Athan
Objective Technologies, Inc.
Date: Fri, 26 Feb 93 14:33:12 -0500
From: athan@object.com (Andrew Athan)
To: billb@jupiter.fnbc.com (Bill Burcham)
Subject: Re: Class Variables
Cc: lupson@geom.umn.edu, gnu-objc@gnu.ai.mit.edu
> Please feel free to FLAME ME WITH IMPUNITY, but this illustrates the fact that it is _wrong_ to have only one interface file per class
In general I vote down on any feature of a language which -requires- that I have multiple files. What are we trying to do, recreate Modula-2?!
>...
>If we did this then a "use" interface would start to look suspiciously like (simply) a protocol.
What you state can already be done with NeXT's objc. Just do this:
//this is my "Usage interface file"
@class ClassA
@protocol ClassAUsage
+ foobar;
- foobar;
@end
// this is my "Subclassing interface file"
@interface ClassA:Object < ClassAUsage >
{
...;
}
@end
// this is my "implementation file"
@implementation ClassA
+ foobar {}
- foobar {}
@end
> So, if I want to associate a protocol with one of my ivars (o.k. GNU doesn't have protocols _yet_, but bear with me) then I have to #import that protocol definition -- even though the user of this class DOESN'T HAVE ANY NEED TO HAVE THAT PROTOCOL IN ITS SCOPE.
This question is just one of "how many are too many" features? As a language definer, I can give you completely normalized declaration/implementation/specification features (normalized = no data repeated, no requirement to have data where you don't need it). As a language implementor (gcc) I can give you fully defered error management. Both are at a cost to complexity, which in the first case impacts at least readability (just from the simple standpoint of # of keywords, concepts to learn, etc.) and in the second at least compile time.
I don't dislike the way things are now in NeXT Obj-C. I do feel the protocol language extension needs work (there are problems stemming from the actual equivalience of + & - methods in obj-c, and from the -implementation- of the compile time "conformsTo:" checks being too restrictive. I feel that it's generally ok to have to include most of the .h's for the AppKit just to use even a simple class. Why? Because probably, in a large system, you'd find yourself having to spend a LOT of time making your .h's orthogonal anyway. Why bother? Just provide things like precomp headers, etc. to make the whole process faster. This way, you make the problems/errors/bugs less likely. Don't worry! Be Happy!
Andrew Athan
Objective Technologies, Inc.
Date: Fri, 26 Feb 93 13:50:51 -0500
From: athan@object.com (Andrew Athan)
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
See Peter's message following my sig. Unless I missunderstand him:
People keep missing the point! Let me make it clear: [This is in pseudo objc to keep things short. I think you understand]
static statCvar;
@implementation SuperClass:Object
{
+ int realCvar;
}
+ initialize { realCvar=statCvar=0; }
+ printRealCvar { printf("%s real: %d",[self name],realCvar); }
+ printStatCvar { printf("%s stat: %d",[self name],statCvar); }
+ inc { realCvar++;statCvar++; }
@end
@implementation SubClass:SuperClass
@end
main()
{
[[SuperClass class] printRealCvar];
[[SuperClass class] printStatCvar];
[[SubClass class] printRealCvar];
[[SubClass class] printStatCvar];
[[SubClass class] inc];
[[SubClass class] inc];
[[SuperClass class] inc];
[[SuperClass class] printRealCvar];
[[SuperClass class] printStatCvar];
[[SubClass class] printRealCvar];
[[SubClass class] printStatCvar];
}
Result:
SuperClass real: 0
SuperClass stat: 0
SubClass real: 0
SubClass stat: 0
SuperClass real: 1
SuperClass stat: 3
SubClass real: 2
SubClass stat: 3
Thus, you see that in a "real" cvar, **each class has its own copy automatically**. With a static variable **all subclasses share the same memory**. Just to prove that it can be implemented: one way is by having the ->isa metaclass struct for a class and its subclasses contain any declared realCvar's appended to the normal isa information. The code realCvar=10; really reads self->isa->realVar=10;.
Andrew Athan
Objective Technologies, Inc.
============================================
Peter Rasmussen writes:
> ...
> Here is my main point. Inheritance of class variables does infact already exist with the static solution.
> ...
> > Currently, in order to subclass this behavior, each
> > subclass would be required to define a new static
> > variable and to override the +counter method.
> >
> > #define CV_SomeClass static int instanceCount; \ +
> > (int)getInstCnt { return instanceCount; } \ +
> > putInstCnt:(int)cnt { instanceCount = cnt; return
> > self; } \ + bumpInstCnt { instanceCount++; return
> > self; } \
>
> No - it is not necesseary to put NEW static class variables into each subclass. (I saw Kenneth use macro'es to make this easier). With this usage static becomes a bad and redundant solution - I agree.
>
> Instead setup a subclass implementors interface for the static class variables. This means giving class methods to make them accessible. These class methods automatically gets inherited by your new IMPLICIT metaclass. And it is the subclass implementors responsibility to respect your subclass interface !!!
>
> Let me give a simple example:
>
> ------------------------ BaseClass --------------
>
> static int count; // the class variable
>
> @implementation BaseClass:Object
> {
> }
> + initialize { count = 5; return self; }
> + (int)getCount { return count; }
> + setCount:(int)i { count = i; return self; }
> @end
>
> ------------------------ ClassA --------------
>
> @implementation ClassA:BaseClass
> {
> }
> + hereAmI { return self; }
> @end
>
> ------------------------ Usage --------------
>
> printf("Initialized %d\n, [BaseClass getCount]);
>
> [ClassA setCount:10];
> printf("New count %d\n", [ClassA getCount]);
>
> ------------------------ Execution --------------
>
> Initialized 5
> New count 10
>
>
> So what is it that you seek by introducing class variables besides what can be achieved by static. OK - I need to set up class methods to access the STATIC class variables. But you would have to do that any way when wrapping the class variables into class-objects (from which there only exist a single anyway)
>
> Regards
>
> Peter Rasmussen
>
Date: Fri, 26 Feb 93 19:18:51 -0500
From: athan@object.com (Andrew Athan)
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
> I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
>
> Lets take Kenneths example classes housekeeping how many instances they have. Sure this task would take a counting variable for each class. Separated yes - but why isolated ? Update of these "class variables" for counting ought to propagate within class methods.
>
> If I instantiate eg. a View, I have also put one more object of all of its superclasses into play. So their instance counts should be updated also ...
>
The fact that static variables solve your example does not prove anything except that static variables are useful. The fact that static variables can be used to build class-variable like functionality also does not prove anything. Neither thing changes the fact that class variables are also useful: In the first case, they solve a different problem. In the second case, remember: C++ can be mapped onto C, and C onto assembler.
Andrew Athan
Objective Technologies, Inc.
Date: Sat, 27 Feb 93 18:52:42 -0800
From: John Jay Feiler
To: burchard@geom.umn.edu
Subject: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
Reply-To: relief!jjfeiler@uu2.psi.com
The only problem with this is that there isn't anything preventing someone from doing the following:
- someMethod
{
Foo *myFoo = [[Foo alloc] init];
.....
}
and getting a different instance of the Foo class. I guess if you override the +alloc and +allocFromZone: methods to raise an exception you can avoid this though.
As far as subclassing goes, using the theFoo = self = [super new] will subclass just as well as the init mechanism. Of course, if a class has only a single instance, then it's subclasses will likely do the same, and will require their own static variables to point to that instance.
John
Begin forwarded message:
Date: Fri, 26 Feb 93 10:25:35 -0600
From: burchard@geom.umn.edu
To: relief!jjfeiler@uu2.psi.com
Subject: Re: Class Variables -- be careful!
Cc: Steve_Naroff@NeXT.COM (Steve Naroff), gnu-objc@gnu.ai.mit.edu
> If we don't allow a class method to access instance vars
> (or reassign self) how should we design objects which
> only have one instance, such as OpenPanel? I usually do
> the following:
If you *must* do it this way, you can always say what you really mean, and display how you are directly accessing another object's ivars:
static Foo *theFoo;
+ new
{
if(theFoo == nil)
{
theFoo = [super new]; //!! relying on super to really alloc
theFoo->glub = 10; //!! directly accessing object's ivars
}
return theFoo;
}
Preferably, though, you would use the protocol that already exists. This will also subclass nicely:
static Foo *theFoo;
+ new
{
if(!theFoo) theFoo = [[self alloc] init];
return theFoo;
}
- init
{
if(![super init]) return nil;
glub = 10;
return self;
}
--------------------------------------------------------------------
Paul Burchard
********** Global variables: the ``GOTO'' of the 90's **********
--------------------------------------------------------------------
Date: Sun, 28 Feb 93 10:32:15 EST
From: jjobe@mrj.com (jason jobe)
To: peter@tahiti.umhc.umn.edu
Cc: rasmus@dannug.dk, gnu-objc@prep.ai.mit.edu
In-Reply-To: Peter Eisch's message of Fri, 26 Feb 93 15:13:55 -0600 <9302262113.AA19988@tahiti.umhc.umn.edu>
Subject: Class Variables
> Put simply, the SCOPE of "Class Variables" should only be the class
> in which they are declared. They should not be visible to subclasses
> though the methods that manipulate them (if necessary) would be
> provided.
The Dylan spec (availabale from Apple) addresses many of the topics which
are being discussed here. One might require one to explicitly specifiy if
each subclass gets its own copy of the the (class)variable or shares the one
being declared.
Jason
Date: Mon, 1 Mar 93 09:28:53 -0600
From: jr@media.com (J.R. Jesson)
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Bill Burcham writes:
[ stuff deleted ]
> Please feel free to FLAME ME WITH IMPUNITY, but this illustrates the fact
> that it is _wrong_ to have only one interface file per class. There is _no_
> reason to have _any_ instance variable definitions in an interface file --
> other than for subclassing purposes. The language would be better if we had
> seperate files for the subclassing interface vs. "use" interface. To avoid
> duplication, we could #import the "use" interface into the subclassing
> interface. NeXT made the situation a _little_ better by providing the @class
> stuff so I don't have to #import irrelevant class interface files, but think
> about it: there is no such mechanism for forward declaration of protocols!
> So, if I want to associate a protocol with one of my ivars (o.k. GNU doesn't
> have protocols _yet_, but bear with me) then I have to #import that protocol
> definition -- even though the user of this class DOESN'T HAVE ANY NEED TO
> HAVE THAT PROTOCOL IN ITS SCOPE.
>
>
> If we did this then a "use" interface would start to look suspiciously like
> (simply) a protocol. The only thing we would have to add to a protocol would
> be some way to get the compiler to see the external declaration of the Class.
> All of the stuff that we are currently putting in our interface would go into
> the subclassing interface.
>
No flames here Bill, but I do have a comment ;-). I think that there is a
difference between what you propose to do here, and what was previously
discussed about Class variables. Class variables give developers a
more direct way to express important things about the Class. What you
propose to do is "protect" the "users" of the compiler from themselves.
I think its a bad idea to overly protect developers from doing "dumb" things. This is probably why I like 'C' and dont like Eiffel. In this case, you
really propose to add a whole level of constraint and syntax to the language
( and the compilers). At the moment, the compiler doesn't care where
@interface and @implementation directives are located, so you add a level
of checking and complexity. You also run the real risk of having to do
changes amongst three files, instead of one or two. Two thumbs down from
the critic...
jr
---
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
J.R. Jesson
Chief Development Dude, All-Around Nice Guy, Wirehead
Multimedia Learning, Inc. (214)869-8282
jr@media.com. - Go Ahead, send NeXTMail!
|