discuss-gnustep
[Top][All Lists]
Advanced

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

Re: Strange crash in __objc_resolve_class_links


From: David Chisnall
Subject: Re: Strange crash in __objc_resolve_class_links
Date: Wed, 16 Feb 2011 14:52:58 +0000

On 16 Feb 2011, at 13:21, Ivan Vučica wrote:

> On Wed, Feb 16, 2011 at 13:22, David Chisnall <theraven@sucs.org> wrote:
> 
>> One of the core points in the Objective-C philosophy is that there should be 
>> a direct correspondence between syntax and semantics.  New semantics should 
>> always involve new syntax, old syntax should not be used for new semantics.  
>> This is very important because it makes it easy to understand what a piece 
>> of code is doing, without having to reference lots of other pieces of code.
>> 
> A good philosophy. Considering that, it might have been wise for Apple to 
> pick another syntax, and I tend to agree with you, Richard and other 
> developers in favor of dropping the dot syntax.

Yes, and talking to people at Apple, the majority of them concur.  The dot 
syntax was a mistake, and some other separator would have been preferred (even 
.. would have been fine).

> However, for the sake of discussion (and to defend my own decision to keep on 
> using dot syntax :-) I will provide a few more arguments.
> 
>  
>>  Contrast this with C++, for example in this line:
>> 
>> doSomething();
>> 
>> In C++, this can be:
>> 
>> - A C function call.
>> - A static C++ member function (semantically equivalent to a C function)
>> - A non-virtual C++ member function, with this as a hidden parameter
>> - A virtual C++ member function, dynamically looked up depending on the type 
>> of the callee
>> 
>> In contrast, this line in Objective-C, the equivalents are:
>> 
>> doSomething();
>> [MyClass doSomething];
>> [self doSomething];
>> 
>> All of these are distinguishable without looking at any other code.  You can 
>> read this and immediately understand the semantics.  This is very important 
>> for readability.
>> 
> While much cleaner than C++, Objective-C 1.0 does have a similar example:
> [NSString stringWithFormat:@"x %d", 5];
> [someString stringByAppendingString:@"something"];
> 
> ObjC syntax does not differentiate between calls to + and - methods. 
> someString might also be a class. You have to look up if it is or if it isn't 
> an instance as opposed to a class method.

True, however you know it is a message send to something that is dynamically 
defined (i.e. stored in a mutable pointer).  Therefore, you don't know the 
exact method that will be called, while you do in the former case (although 
categories mean that you don't always know the exact method implementation that 
will be called, you do know the path that the lookup will take).

>> Contrast this now with the dot syntax:
>> 
>> a.foo;
>> 
>> This can be:
>> 
>> - A structure member reference
>> 
> Just as you have to look up whether a symbol is a class or an instance, here 
> you have to look up if it's a struct or an object.

Except that classes in Objective-C ARE objects, while structures are not.  If 
you use a class where you were expecting an object, stuff just works.  If you 
use a structure where you expect an object, things go badly wrong.

>> - An Objective-C message send calling a synthesised method that access a 
>> property
>> - An Objective-C message send that calls a user-written method that may have 
>> complex side effects
>> 
> Solution is the very discussion we're having, and spreading information to 
> warn developers about possible consequences. Aside from dropping dot-syntax, 
> another possible suggestion could be that user-provided methods should be 
> carefully written, weighing whether or not to add complex behavior.

Yes, if the dot notation had been properly considered then it would have 
enforced these additional requirements:

- Accessor methods supplied for properties must not have side effects
- Accessor methods supplied for properties must always return the value 
provided for the last set operation.
- Only methods declared with @property may be called with the dot notation

If they had made these requirements, then the dot notation would have added 
something of value to the language.  At present, it is semantically equivalent 
to a message send and may be used interchangeably with a message send.  Since 
it is semantically equivalent, it does not provide any more information to the 
reader or to the compiler, it just does something that looks like a field 
access (which is one of the fastest operations in C) and actually makes it into 
a message send or two (which are an order of magnitude slower), making it hard 
to reason about the behaviour of the code.  

>> This can be made much worse by things like:
>> 
>> a.foo++;
>> 
>> This is equivalent to:
>> 
>> [a setFoo: [a foo]+1];
>> 
> I disagree that this is a downside :-)

Exactly.  Consider reading the two cases.  In the latter, it is obvious that 
you are doing two message sends and an increment.  The naming conventions make 
it clear that these are probably (but not necessarily) simple accessor methods. 
 

In the former case, these observations are also true, but they are not obvious. 
 It's only clear that it's two message sends when you think about how the dot 
notation is implemented.  It's strongly implied that these are accessor 
methods, but the dot notation can be used call any method, so it's not aways 
the case.

>> But the syntax completely hides the fact that you're doing two method calls. 
>>  It lets you write code that is very complex, but with this complexity 
>> completely hidden in the source.  This is particularly dangerous with atomic 
>> properties, because you'd intuitively assume that ++ on an atomic property 
>> is an atomic operation, but it isn't.
> 
> I really think that this is a minor issue and that extra brackets in such 
> short statements do not contribute to readability of code. Most often, one 
> will not write code that will depend on atomicity of the operation. I don't 
> write multithreading code because I don't want to worry about atomicity, 
> locking, race conditions, et cetera.

Then I hope you never have to write any code that is CPU dependent, since 
current trends are towards lots of slower cores.

> I do not argue that everyone must use the dot-syntax, I just don't see that 
> it is such a major problem. It is a nice convenience that can be quite useful 
> to experienced developers. I do see the dangers of dot-syntax in the hands of 
> beginners; I've worked enough with kids and grownups to see what kind of 
> troubles they have, and indeed it could be an issue. 

It is not just dangerous for beginners, it is a syntactic addition without a 
corresponding addition.  It adds another way of writing the same thing.  The 
only pseudoadvantage is brevity.  This is the same argument that can be made in 
favour of Smalltalk's -at:put:, instead of OpenStep's -setObject:forKey: and 
-replaceObjectAtIndex:withObject:.  The former is definitely less to type, but 
if you are spending more time typing than thinking while programming, then you 
are Doing It Wrong™.  Most code is read more times than it is written - 
especially open source code - and a second saved in typing can easily translate 
to a minute or more spent understanding the code.  

> But whenever I use dot-syntax, I am very conscious of what I'm doing; I am 
> conscious that I am making a method call (or two!) and it's not an issue. 
> And, after all, large majority of my properties are synthesized. What harm in 
> using that?

You are thinking about yourself, not about the people reading your code.  This 
is the fastest path to unmaintainable code that I have encountered.  I can 
point to places in GNUstep and other projects where people have had the same 
philosophy.  These people have subsequently moved on to other projects, and no 
one wants to touch the code.  

> Finally, let me restate that I do see what bothers you, and I do agree with 
> your stance a bit more. I do not, however, consider that we should call the 
> dot-syntax deprecated, or avoid it when writing applications.

If I don't have to read your code, then you can do whatever you want.  In 
GNUstep, we don't use this syntax for exactly the same reason that we use 
descriptive method names, explanatory comments, and so on - it's an open source 
project and other people have to read the code.  

David

--
This email complies with ISO 3103


reply via email to

[Prev in Thread] Current Thread [Next in Thread]