discuss-gnustep
[Top][All Lists]
Advanced

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

Re: [objc-improvements] Just remembered something about multiplemethod s


From: Ziemowit Laski
Subject: Re: [objc-improvements] Just remembered something about multiplemethod signatures...
Date: Mon, 8 Sep 2003 17:25:59 -0700


On Monday, Sep 8, 2003, at 16:19 US/Pacific, Alexander Malmberg wrote:

David Ayers wrote:
Ziemowit Laski wrote:
On Saturday, Sep 6, 2003, at 00:54 US/Pacific, David Ayers wrote:

Given
Class1: -(id)test1Float:(float)f int:(int)i;
Class2: -(Object *)test1Float:(float)f int:(int)i;

In the old case, you could get a warning about the compiler picking
the wrong prototype but the results were correct.


In this particular case, the compiler picked a method signature out of
a hat that happened to work in that the intended codegen occurred.

In this case, it didn't just "happen to work".

Sure it did. You just happened to have two signatures that didn't differ by that much.
Throw in

   -(double)test1Float:(int)f int:(float)i;
   -(void)test1Float:(float)f int:(int)i;
   -(struct foo)test1Float:(struct bar)f int:(int)i;

and now tell me that it still happens to work. :-)


Class3: -(void)test1Float:(float)f int:(int)i;
 Note that it doesn't
matter which prototype the compiler picks, the program will do the right
thing anyway. However, if the compiler ignored both prototypes and used
the fallback, it wouldn't work since the float argument would be
promoted to a double.

In this particular case, yes, you get lucky with the existing approach. In other cases, you'll get lucky with the IMP approach instead. But neither the current approach nor the IMP approach can _ever_ be described as correct in any meaningful sense, since the underlying conflict is not solvable in the general case. :-( This is why it has been suggested by David and Steve that this situation really calls for a hard error instead of a warning. But, if we absolutely _insist_ on a warning, then I still maintain that my IMP approach has the advantage of, at the very least, offering a consistent fallback instead of the pseudo-magic that
currently occurs.


This seems to be the primary technical advantage of picking a random
prototype. If all the prototypes are "mostly" compatible, it will do the
Right Thing without any advanced merging rules. IOW, it does well when
the conflicts are minor, but potentially fails completely (picks the
wrong one) when the conflict is big.

The fallback prototype approach's kindof-sortof tries to guess the
prototype from the arguments (by assuming that the prototype should have
the same types as the arguments). IOW, it can handle any conflict
decently, but always with a big risk of messing up completely (promoted
types, or the return type).

This is a good comparison of the _effect_ of the two approaches. However, the IMP approach does not attempt to guess or infer anything from anything -- IMP is used whenever there are conflicting methods (or no methods), period. I would argue that this simplicity is a virtue, from the end-users' viewpoint. :-)

Anyway, at this point, I find it very unlikely that we're going to be
able to agree that some solution is substantially better than all
others. Thus, I don't think that it will be worth breaking compatibility
to get any new behavior. I'm going to restore the old behavior in my
patch (when searching for a prototype among all prototypes (ie. not for
a specific type), and there are several prototypes, a warning is issued
and a "random" prototype is used).

Theoretical objections aside, can you point me to a specific case in actual
code (in GNUStep or elsewhere) where where the new IMP "behavior" breaks
"compatibility"?  And even if it does, what prevents you from typing the
receiver more strongly (which ObjC hygiene dictates you should do anyway) in cases of conflicts? :-) If you have multiple method conflicts in your code, you're playing with fire regardless of whether you're falling back to IMP or
not. :-)


But just because the "results were correct" in this case does not make
the compiler correct. :-(  In fact, all you need to do here is add

  Class3: -(void)test1Float:(float)f int:(int)i;

to see just how "incorrect" things can get. :-)

:-) but this protoype is not just a conflicting prototype, it's an
outright incompatible prototype, and as I believe Steve Naroff already
suggested, it may be wiser to emit a hard error

I disagree. A warning and almost any behavior is better than a hard
error.

Only if you're an expert user (the joke about the car designed by UNIX gurus comes to mind). If you're a developer learning Objective-C, you'll either ignore the warnings at your peril, or file bugs about mysterious errors and warnings produced
by the compiler.

Having the entire compile fail because the compiler isn't
sure that it's doing the right thing does not seem particularly useful

(gasp)

(especially in objective-c, where the compiler can _never_ be really
sure that it's doing the right thing).

In the case we're discussing here, the compiler is quite sure it _cannot_
do the right thing.  :-)

--Zem
--------------------------------------------------------------
Ziemowit Laski                 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group        Cupertino, CA USA  95014-2083
Apple Computer, Inc.           +1.408.974.6229  Fax .5477





reply via email to

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