Calling the Language Lawyers.. (using the ?: operator in Obj-C.)
-
Sorry if you're seeing this for the second time, but mail crashed just
as I was sending it the first time, and I'm not sure if it got out.
-jcr
On Monday, June 4, 2001, at 05:24 AM, John C. Randolph wrote:
>"The problem with trying to child-proof the world, is that it makes
> I'm trying to shorten some MiscKit code, and GCC complains about
>
> parse error before `:'
>
> from this code:
>
> timeSpans =
> [([[self class] isMutable] ? NSMutableSet : NSSet)
> setWithObjects:aSpan, nil];
>
> which looks kosher to me.
>
> When I changed it to:
>
> timeSpans =
> [[[self class] isMutable] ? [NSMutableSet class] : [NSSet class]
> setWithObjects:aSpan, nil];
>
> the compiler quit complaining.
>
> So, I've got a workaround, but I'm still wondering why the compiler
> won't allow classes in a ?: statement. They're just objc_Class *'s at
> compile time, aren't they?
>
> -jcr
>
>
people neglect the far more important task of world-proofing the
child." -- Hugh Daniel
>
-
John C. Randolph Calling the Language Lawyers.. (using the ?: operator in Obj-C.) Jun 04 2001, 07:54I'm trying to shorten some MiscKit code, and GCC complains about
parse error before `:'
from this code:
timeSpans =
[([[self class] isMutable] ? NSMutableSet : NSSet)
setWithObjects:aSpan, nil];
which looks kosher to me.
When I changed it to:
timeSpans =
[[[self class] isMutable] ? [NSMutableSet class] : [NSSet class]
setWithObjects:aSpan, nil];
the compiler quit complaining.
So, I've got a workaround, but I'm still wondering why the compiler
won't allow classes in a ?: statement. They're just objc_Class *'s at
compile time, aren't they?
-jcr
"The problem with trying to child-proof the world, is that it makes
people neglect the far more important task of world-proofing the
child." -- Hugh Daniel -
On Monday, June 4, 2001, at 02:24 , John C. Randolph wrote:
> I'm trying to shorten some MiscKit code, and GCC complains about
>
> parse error before `:'
>
> from this code:
>
> timeSpans =
> [([[self class] isMutable] ? NSMutableSet : NSSet)
> setWithObjects:aSpan, nil];
>
> which looks kosher to me.
>
> When I changed it to:
>
> timeSpans =
> [[[self class] isMutable] ? [NSMutableSet class] : [NSSet class]
> setWithObjects:aSpan, nil];
>
> the compiler quit complaining.
>
> So, I've got a workaround, but I'm still wondering why the compiler won't
> allow classes in a ?: statement. They're just objc_Class *'s at compile
> time, aren't they?
IANALL, but "NSSet" is a type, not a class. You can't do the following:
[NSSet class] aSet; // instead of
NSSet aSet;
And you can't do
(a?int:float) aNumber;
So calling [NSSet alloc] isn't really correct, but [[NSSet class] alloc]
wouldn't be better :)
andy
--
Description forthcoming. -
On Mon, 4 Jun 2001, John C. Randolph wrote:
> I'm trying to shorten some MiscKit code, and GCC complains about
>
> parse error before `:'
>
> from this code:
>
> timeSpans =
> [([[self class] isMutable] ? NSMutableSet : NSSet)
> setWithObjects:aSpan, nil];
>
> which looks kosher to me.
>
> When I changed it to:
>
> timeSpans =
> [[[self class] isMutable] ? [NSMutableSet class] : [NSSet class]
> setWithObjects:aSpan, nil];
>
> the compiler quit complaining.
>
> So, I've got a workaround, but I'm still wondering why the compiler
> won't allow classes in a ?: statement. They're just objc_Class *'s at
> compile time, aren't they?
Nope. A class name is not a valid expression, and can only legally be used
as the recipient of a message send. I had a sort-of similar problem trying
to fill an array with some classes. Doing array[3] = MyClass broke;
array[3] = [MyClass class] worked. The ? operator doesn't do a simple
test-and-replace, so each of its parts must contain a complete and valid
expression, which a class name isn't.
--
"From now on, we live in a world where man has walked on the moon.
And it's not a miracle, we just decided to go." -- Jim Lovell
Mike Ash - <http://www.mikeash.com/>, <mailto:<mail...> -
On Mon, 4 Jun 2001, John C. Randolph wrote:
> So, I've got a workaround, but I'm still wondering why the compiler
> won't allow classes in a ?: statement. They're just objc_Class *'s at
> compile time, aren't they?
>
If I've got my terminology right, it's because Objective-C doesn't have
higher-order types. Consider:
NSSet *blah; //(NSSet *) is a type, blah is a variable
Class nsSet; //Class is a type, nsSet is a variable
blah = [NSSet set]; //NSSet is used here as a variable
name whose value is the definition of the class NSSet
nsSet = NSSet; //this fails because NSSet _isn't_ considered a variable
name in this context.
nsSet = [NSSet class]; //again, as the receiver of a message NSSet is
interpreted as a variable
blah = [nsSet set]; //succeeds as nsSet's value is now the NSSet class
So the C-heritage is showing though. You can't do
variable = int;
either. With higher-order types you could do:
Class nsSet = NSSet;
nsSet blah;
blah = [nsSet set];
--
Ian P. Cardenas
Computer Scientist, Software -
On Monday, June 4, 2001, at 07:27 Uhr, Michael J Ash wrote:
>> So, I've got a workaround, but I'm still wondering why the compiler
>> won't allow classes in a ?: statement. They're just objc_Class *'s at
>> compile time, aren't they?
>
> Nope. A class name is not a valid expression, and can only legally be
> used
> as the recipient of a message send. I had a sort-of similar problem
> trying
> to fill an array with some classes. Doing array[3] = MyClass broke;
> array[3] = [MyClass class] worked. The ? operator doesn't do a simple
> test-and-replace, so each of its parts must contain a complete and valid
> expression, which a class name isn't.
The interesting thing here is that this used to be different, class
names were just normal values. I am not sure why the change was made,
but it seems to have occured around OPENSTEP times.
Marcel -
Marcel Weiher <marcel...> said:
>
> On Monday, June 4, 2001, at 07:27 Uhr, Michael J Ash wrote:
>
>>> So, I've got a workaround, but I'm still wondering why the compiler
>>> won't allow classes in a ?: statement. They're just objc_Class *'s at
>>> compile time, aren't they?
>>
>> Nope. A class name is not a valid expression, and can only legally be
>> used
>> as the recipient of a message send. I had a sort-of similar problem
>> trying
>> to fill an array with some classes. Doing array[3] = MyClass broke;
>> array[3] = [MyClass class] worked. The ? operator doesn't do a simple
>> test-and-replace, so each of its parts must contain a complete and valid
>> expression, which a class name isn't.
>
> The interesting thing here is that this used to be different, class
> names were just normal values. I am not sure why the change was made,
> but it seems to have occured around OPENSTEP times.
Now that's interesting!
This thread got me to thinking that I had always thought the [MyClass class] construct
was unfortunately clumsy, I would prefer to treat the MyClass symbol as a class object
directly rather than use [MyClass class]. I didn't realize that this was actually the
way things used to be.
One thing that struck me when thinking about it is that static typing probably wouldn't
mix well with this convention. It would probably be hard to convince the compiler that
MyClass*, YourClass*, and AnotherClass* are all different types and at the same time
that MyClass, YourClass and AnotherClass are all values of type objc_Class*. It would
be doable but it looks like you'd have to do some extensive rewriting of the C portion
of the compiler's syntax rules, which would be undesireable if you are trying to
maintain a legal C compiler at the same time. (The treatment at the beginning of the
square brackets is a different matter, since it involves Objective C syntax rules which
are obviously disjoint from the C syntax rules at that point).
Since I know static typing was not an original feature of Objective C, this makes me
wonder: was static typing possibly introduced around the same time that this change in
the treatment of class names occurred?
- Dennis D.



