why are overloaded methods statically bound?

S

sticky

Hello all,

Anyone know why aren't overloaded methods dynamically bound, like
overridden methods? My guess at this point is that having both be
dynamically bound might create paradoxes, but that's a wild guess. It
does seem like if it were possible, it would have been better if they
were both the same, both dynamically bound.

TIA
-aline
 
D

Dale King

Hello all,

Anyone know why aren't overloaded methods dynamically bound, like
overridden methods? My guess at this point is that having both be
dynamically bound might create paradoxes, but that's a wild guess. It
does seem like if it were possible, it would have been better if they
were both the same, both dynamically bound.


I'm not sure if paradox is the word I would use, but you certainly end up
with ambiguous situations. Imagine if you had methods:

void method( Object o ) { ... }
void method( InterfaceA a ) { ... }
void method( InterfaceB a ) { ... }

Object o = new ClassThatImplementsInterfaceAandB()

If I call the method with o which method is supposed to be called?

The problem grows exponentially as the number of parameters is increased.

The other problem is performance. It would be quite a performance hit and
quite the hard task to have to examine the types of the arguments and search
for the correct method to call. On the contrary, the dynamic binding of
overridden methods is fast and easy.
 
T

Thomas G. Marshall

Dale King said:
I'm not sure if paradox is the word I would use, but you certainly
end up with ambiguous situations. Imagine if you had methods:

void method( Object o ) { ... }
void method( InterfaceA a ) { ... }
void method( InterfaceB a ) { ... }

Object o = new ClassThatImplementsInterfaceAandB()

If I call the method with o which method is supposed to be called?

Javac will actually prompt you with an error asking you to specifically cast
the actual parameter so it knows:

method((Object)o);
method((InterfaceA)o);
method((InterfaceB)0);
 
J

Joona I Palaste

I'm not sure if paradox is the word I would use, but you certainly end up
with ambiguous situations. Imagine if you had methods:
void method( Object o ) { ... }
void method( InterfaceA a ) { ... }
void method( InterfaceB a ) { ... }
Object o = new ClassThatImplementsInterfaceAandB()
If I call the method with o which method is supposed to be called?
The problem grows exponentially as the number of parameters is increased.

You don't need interfaces.

void method(Object a, Object b, Object c, Object d, Object e) { ... }
void method(Object a, Object b, Object c, Object d, String e) { ... }
void method(Object a, Object b, Object c, String d, Object e) { ... }
void method(Object a, Object b, Object c, String d, String e) { ... }
/* and so on... */
void method(String a, String b, String c, String d, String e) { ... }
/* that is, 32 overloaded methods */

method(null, null, null, null, null);

Now which of the 32 versions is the JVM supposed to pick?
 
J

Joona I Palaste

Javac will actually prompt you with an error asking you to specifically cast
the actual parameter so it knows:
method((Object)o);
method((InterfaceA)o);
method((InterfaceB)0);

Well yes it does, but that's *precisely* because they are statically
bound. If they were dynamically bound javac wouldn't be able to do squat.
 
T

Thomas G. Marshall

Javac will actually prompt you with an error asking you to
specifically cast the actual parameter so it knows:

method((Object)o);
method((InterfaceA)o);
method((InterfaceB)0);

Clarification. I don't really remember what javac does.

The old visual cafe for java compiler used to do precisely that. I just
figured that it was part of the jls.

And I'm crummy at finding things in the jls---and I cannot find it.
 
M

Michael Borgwardt

Thomas said:
Javac will actually prompt you with an error asking you to specifically cast
the actual parameter so it knows:

method((Object)o);
method((InterfaceA)o);
method((InterfaceB)0);

But that was Dale's *point*, wasn't it? Static binding ensures that the compiler
can force you to resolve such ambiguities. To use dynamic binding, they would either
have to be resolved through arbitrary rules (causing confusing behaviour of
the code) or through runtime exceptions (causing crashes).
 
T

Thomas G. Marshall

Michael Borgwardt said:
But that was Dale's *point*, wasn't it? Static binding ensures that
the compiler can force you to resolve such ambiguities. To use
dynamic binding, they would either have to be resolved through
arbitrary rules (causing confusing behaviour of
the code) or through runtime exceptions (causing crashes).

Yep. My apologies.
 
C

Chris Riesbeck

Dale King said:
I'm not sure if paradox is the word I would use, but you certainly end up
with ambiguous situations. Imagine if you had methods:

void method( Object o ) { ... }
void method( InterfaceA a ) { ... }
void method( InterfaceB a ) { ... }

Object o = new ClassThatImplementsInterfaceAandB()

If I call the method with o which method is supposed to be called?

This can be handled if the language designers so choose. Common Lisp
and Dylan and probably others define precedence rules to resolve all
ambiguities, using information such as what order you specified A and
B when defining the new class.
The problem grows exponentially as the number of parameters is increased.

The other problem is performance. It would be quite a performance hit and
quite the hard task to have to examine the types of the arguments and search
for the correct method to call. On the contrary, the dynamic binding of
overridden methods is fast and easy.

Again, if the language designers want to support this, there are
techniques for constructing pretty fast table lookups. Common Lisp
implementors have to work extra hard since new classes can be defined
at any time.
 
J

John C. Bollinger

Joona said:
Well yes it does, but that's *precisely* because they are statically
bound. If they were dynamically bound javac wouldn't be able to do squat.

Yes, and then the ambiguity would manifest at runtime. Rules to choose
one method over the others could be applied, but no such rule set could
be expected to reliably choose the right one. Much better to detect the
problem at compile time and make the programmer fix it.


John Bollinger
(e-mail address removed)
 
C

Chris Smith

Chris said:
Again, if the language designers want to support this, there are
techniques for constructing pretty fast table lookups. Common Lisp
implementors have to work extra hard since new classes can be defined
at any time.

But wait: that's also true of Java! I doubt Common Lisp or this
hypothetical language called Java-With-Dynamic-Binding-On-Parameters
could match (or even come close to) existing polymorphism, on the
message recipient only, when looking up method dispatch based on
parameter object classes.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Thomas said:
And I'm crummy at finding things in the jls---and I cannot find it.

If anyone is looking, it's the latter part of section 15.12.2.2 ("Choose
the Most Specific Method"), with an example provided in 15.12.2.3
("Example: Overloading Ambiguity").

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Riesbeck

Chris Smith said:
But wait: that's also true of Java! I doubt Common Lisp or this
hypothetical language called Java-With-Dynamic-Binding-On-Parameters
could match (or even come close to) existing polymorphism, on the
message recipient only, when looking up method dispatch based on
parameter object classes.

Sorry, I didn't understand your first sentence at all. *What's* also
true of Java?

And I'm not sure what you meant by "match existing polymorphism." Do
you mean performance? If so, I didn't say it did. I said "pretty
fast." It's fast enough for tons of Lisp applications doing graphics
and web servers and so on. But multi-method dispatch is going to cost
something, just like method dispatch costs, compared to a C function
call. It's a tradeoff -- speed for programming flexibility. Java is
one valid set of trade offs, C++ another, Lisp another.
 
C

Chris Riesbeck

Michael Borgwardt said:
But that was Dale's *point*, wasn't it? Static binding ensures that the compiler
can force you to resolve such ambiguities. To use dynamic binding, they would either
have to be resolved through arbitrary rules (causing confusing behaviour of
the code) or through runtime exceptions (causing crashes).

Whether the behavior is confusing depends on the rules. I've never
been confused by Lisp's method dispatch resolution rules. I've been
frequently confused by C++'s when lookup interacts with namespaces.
But each language, Java included, gives me certain features in
exchange for its confusing aspects.
 
C

Chris Smith

Chris said:
Sorry, I didn't understand your first sentence at all. *What's* also
true of Java?

That new classes can be defined at any time.
And I'm not sure what you meant by "match existing polymorphism." Do
you mean performance? If so, I didn't say it did. I said "pretty
fast."

Okay, then we don't disagree.

Nevertheless, it seemed appropriate to point out that this isn't just a
"the language designers didn't care enough" kind of situation that your
post suggested it was. There are valid reasons why even a good
implementation of a language with parameter-based polymorphism would
have weaknesses compared to a language without it; and both the
difficulty of predicting dispatch with that many factors involved and
the very real performance issues (which extend beyond the language
designer not being clever enough) are valid reasons that have been
mentioned in this thread.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Riesbeck

Chris Smith said:
Okay, then we don't disagree.

Nevertheless, it seemed appropriate to point out that this isn't just a
"the language designers didn't care enough" kind of situation that your
post suggested it was.

My post said "This can be handled if the language designers so
choose." and "Again, if the language designers want to support
this,..."

How does that turn into "the language designers didn't care enough?"
There are valid reasons why even a good
implementation of a language with parameter-based polymorphism would
have weaknesses compared to a language without it;

and strengths. If it was all weaknesses, no one would do it. If it was
all strengths, no one would not do it.
and both the
difficulty of predicting dispatch with that many factors involved

What's your evidence for this? It's messy in C++ because namespaces
are involved. But I've not seen any results that show programmers in
the Common Lisp Object System (CLOS) have any trouble here with normal
programming.
and
the very real performance issues (which extend beyond the language
designer not being clever enough) are valid reasons that have been
mentioned in this thread.

No one gave any performance metrics here or cited any "very real
performance measures." Googling for "multimethod dispatch performance"
finds a number of results such as constant-time lookup for Cecil, and
modest to no penalty for an multimethod extension to Java, and that
was in the first few search results.

A key result in the Java article is that doing multimethod dispatch by
hand, which is what programmers have to do currently, writing
instanceof calls, is SLOWER by a wide margin that what a compiler can
do with multimethods supported.

Cecil: http://portal.acm.org/citation.cfm?doid=271510.271521

Java: http://citeseer.nj.nec.com/dutchyn01multidispatch.html

And just to make it clear: I'm not saying Lisp is better than Java,
and I'm not saying Java should have multimethod dispatch. I'm simply
trying to point out that things aren't as black and white about the
complexity and performance tradeoffs as some of the postings have
suggested. There are perfectly usable languages that have made
decisions differently than the Java designers did.
 
C

Chris Smith

Chris said:
My post said "This can be handled if the language designers so
choose." and "Again, if the language designers want to support
this,..."

How does that turn into "the language designers didn't care enough?"

Okay, let's put this in context. Original poster asks why Java doesn't
base polymorphism on parameter types. Someone responds saying
performance. You respond saying "this can be handled if the language
designers so choose." So, what you said is that the performance impact
is solvable, and there's some *other* reason for the choice instead.
You may not have meant to say that, but you clearly did.

I objected, and you made some statement about "different trade-offs" and
"fast enough" to imply that you were minimizing the importance of
performance. I agreed that this is sometimes the case.

The "didn't care enough" was hyperbole on my part. You haven't said
what other reasons you believed the language designers to have in
omitting the feature, if indeed you believe it to be the case.
and strengths. If it was all weaknesses, no one would do it. If it was
all strengths, no one would not do it.

Of course! That's not the issue. The issue is that when someone
pointed out the weaknesses, you jumped in and and said "that can be
handled" as if it weren't an issue.
What's your evidence for this? It's messy in C++ because namespaces
are involved. But I've not seen any results that show programmers in
the Common Lisp Object System (CLOS) have any trouble here with normal
programming.

Messy in C++? It doesn't even exist in C++! The difficulty in
predicting method dispatch on so many factors is explained merely by the
observation that there are so many more factors involved. That
implicitly makes it harder to predict. Frankly, I think the amount of
difficulty people have with just static resolution of overloaded
parameter types indicates great trouble in that direction.

I don't know anything about CLOS programmers, so I can't speak one way
or the other about whether they are confused. I can only point out that
there is a much longer and more complex process involved than is
generally the case.
No one gave any performance metrics here or cited any "very real
performance measures." Googling for "multimethod dispatch performance"
finds a number of results such as constant-time lookup for Cecil, and
modest to no penalty for an multimethod extension to Java, and that
was in the first few search results.

It would take a good bit more effort than USENET is worth for someone to
put together a comparative benchmark of performance between a real
language and a hypothetical language.

You provide a pseudo-comparison in which the authors compare the
techniques using a worst case scenario piece of code, and even then
conspicuously avoid quoting results of the original code running on an
unaltered modern virtual machine using standard JVM performance
techniques. Instead, they represent "normal" with an interpreted VM; a
meaningless number, as we all know. Furthermore, even this paper making
the case for such method dispatch in Java doesn't dare apply it
universally. Instead, they mark a few very specific places to use the
technique using a marker interface, recognizing that it's not
universally applicable.

(As for constant time, I should certainly hope that method dispatch is
constant time! That's generally considered a basic assumption in
programming languages, not an accomplishment. The challenges in
practical optimization of language implementations relate to minimizing
the cache touches of the process and thus chance of a page fault, the
plain processor cycles involved, etc.)

I'm all for giving something a fair shot, but I think you're
misrepresenting the issue by claiming that general polymorphism on
parameters in Java might possibly not have a performance impact.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Riesbeck

Chris Smith said:
Okay, let's put this in context. Original poster asks why Java doesn't
base polymorphism on parameter types. Someone responds saying
performance. You respond saying "this can be handled if the language
designers so choose."

That's not the correct context.

My posting was in response to Dale King's comment about ambiguous
method calls, the one that started with "I'm not sure if paradox is
the word I would use, but you certainly end up with ambiguous
situations. Imagine if you had methods:..."

I was pointing out that his example is only ambiguous if the language
designers don't define a resolution rule. They didn't in C++, they did
in CLOS.

It would take a good bit more effort than USENET is worth for someone to
put together a comparative benchmark of performance between a real
language and a hypothetical language.

Where did I point to USENET? I gave a couple links to a masters thesis
and an article from the peer-reviewed ACM Transactions on Programming
Languages and Systems, and that's the tip of the iceberg. People have
been developing techniques for making multimethod dispatch usable
and/or competitive -- which is not the same as cost-free -- for years.
You provide a pseudo-comparison in which the authors compare the
techniques using a worst case scenario piece of code,

They didn't do worst case code, they did common case code, namely what
most programmers do with multimethod dispatch: write a sequence if
instanceof tests. Sure you can do better if you work at it. The point
is that it's better if the compiler writers did that work for you.
I'm all for giving something a fair shot, but I think you're
misrepresenting the issue by claiming that general polymorphism on
parameters in Java might possibly not have a performance impact.

As far as I can tell, you're not, at least on this particular point,
since you've repeatedly misquoted me and misinterpreted my points in
the worst possible way.

I'm sure this is long past the interest of any other readers. Feel
free to grab the last word.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top