<html>
<head>
</head>
<body>
<br>
Paul Foley wrote:<br>
<blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
  <pre wrap="">On Fri, 23 Aug 2002 10:14:08 -0700, James J Besemer wrote:<br></pre>
  <blockquote type="cite">
    <pre wrap="">Just Plain Wrong, certainly depends on what you're used to.<br></pre>
    </blockquote>
    <pre wrap=""><!---->You mean if you're used to languages that do the wrong thing, you<br>probably don't notice that it's wrong?  Doesn't make it any less<br>wrong, though.</pre>
    </blockquote>
I meant it in the exact same same vein that Pythonistas say all the time
about Python -- work around what you perceive to be a problem or limitation
and after a while you'll get used to it and come to accept that it's not
a problem.  I can see how the way C++ works in this case would be confusing
for some, especially newbies, but it ceases to be a problem after you learn
the language.<br>
    <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
      <pre wrap="">No, that's completely irrelevant.  Casting, automatic or otherwise,<br>really has nothing to do with it.</pre>
      </blockquote>
      <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
        <pre wrap="">If you used "virtual" it would work, regardless of any casts.</pre>
        </blockquote>
        <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
          <pre wrap="">You obviously didn't try it.  It won't do what you say it will.</pre>
          </blockquote>
You're right.  I was wrong about this, as I acknowledged earlier. <br>
          <br>
I actually did try it but I did the harder example first and forgot to remove
'virtual' for the simpler case.<br>
          <br>
FWIW, I blame this and other careless errors on the fact that I had been
up for about 24 hours straight at the time.
          <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
            <pre wrap="">consider the possibility that if you<br>knew it better, you might think it was more "Wrong".</pre>
            </blockquote>
Anything is possible but I don't think so.  <br>
            <br>
For it to work the way you expect requires a late binding model -- a table
lookup for each access because nothing can be relied upon at compile time.
 This is inconsistent with the whole design philosophy of C++, which fixes
all name and type bindings at compile time.<br>
            <br>
For better or worse, the truly innovative thing about C++ to be that it offers
most of the flexibility of other OOP languages (Polymorphism for example)
while still providing a strong compile time type checking and binding of
all symbolic references at link time.  That is OOP without the traditional
runtime penalty.  Now maybe Stroustrup was barking up the wrong tree all
the time striving to maintain these objectives (no GC either) but it's an
certainly important accomplishment in the history of programming languages.
 Borland's Delphi made similar strategic design decisions, so maybe it's
not totally crazy.<br>
            <br>
The trade off is that your OOP application can run at machine speeds without
all the considerable overhead doing dictionary hash table lookups for each
name reference.<br>
            <br>
The difference is dramatic:<br>
            <br>
    <a class="moz-txt-link-freetext" href="http://cascade-sys.com/~jb/Pythonetics/callcost/index.htm">http://cascade-sys.com/~jb/Pythonetics/callcost/index.htm</a><br>
            <br>
The 100X or 200X runtime penalty clearly illustrates the difference between
early and late binding, IMO.<br>
            <br>
Now, whether the cost of the extra declarative burden (not to mention the
other complexities of C++) are worth the runtime savings depends on your
application.  In many cases it is a loss because it takes more programmer
time ,which (in most cases) is way more valuable than computer time.  But
sometimes the performance is worth the cost.  It's good to have the choice
and it's good that you don't have to abandon OOP to reap the benefits.<br>
            <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
              <blockquote type="cite">
                <pre wrap="">Clearly we disagree on the definition of Polymorphism.  I think most authorities<br>agree that C++ has Polymorphism as demonstrated above.<br></pre>
                </blockquote>
                <pre wrap=""><!---->C++ does have polymorphism, noone's denying that.  But what you<br>demonstrated above is not it.  To get polymorphism in C++, you use<br>"virtual".</pre>
                </blockquote>
Clearly we disagree and maybe we never will agree.<br>
                <br>
I've cited public 3rd party definitions previously and you've ignored them.
 Here's SEVERAL MORE that support my broader view of Polymorphism (which
expressly includes operator overloading).  <br>
                <br>
     <a class="moz-txt-link-freetext" href="http://whatis.techtarget.com/definition/0,,sid9_gci212803,00.html">http://whatis.techtarget.com/definition/0,,sid9_gci212803,00.html</a><br>
                <br>
     <a class="moz-txt-link-freetext" href="http://www.cyberdyne-object-sys.com/oofaq/oo-faq-S-2.1.0.5.html">http://www.cyberdyne-object-sys.com/oofaq/oo-faq-S-2.1.0.5.html</a><br>
                <br>
     <a class="moz-txt-link-freetext" href="http://www.javaworld.com/javaworld/jw-04-2001/jw-0413-polymorph.html">http://www.javaworld.com/javaworld/jw-04-2001/jw-0413-polymorph.html</a><br>
                <br>
     <a class="moz-txt-link-freetext" href="http://www.ida.his.se/ida/~jonas/ComponentSoftwareCourse/ch6-team2.pdf">http://www.ida.his.se/ida/~jonas/ComponentSoftwareCourse/ch6-team2.pdf</a><br>
                <br>
 Now to be sure, within the context of specific languages and environments,
I have seen narrower definitions of the term.  But in these cases they're
defining how Polymorphism works in that particular language or environment,
where there's no point in discussing the more general forms which do not
exist.  <br>
                <br>
I think we actually pretty much agree on how this all works.  It's just the
definitions of terms where we differ.  Just accept that Polymorphism can
be done in as static fashion and that it does not necessarily involve objects
(as my many sources above indicate) and we won't have an argument.
                <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                  <blockquote type="cite">
                    <pre wrap="">The latter reference points out that C++ provides genuine Polymorphism without<br>using objects at all:<br></pre>
                    </blockquote>
                    <blockquote type="cite">
                      <pre wrap="">    int IsaT1( T1 a ){ return 1; }<br>    int IsaT1( T2 b ){ return 0; }<br></pre>
                      </blockquote>
                      <blockquote type="cite">
                        <pre wrap="">IsaT1( x );    // returns 0 or 1 depending on arg type<br></pre>
                        </blockquote>
                        <pre wrap=""><!----><br>Only it /doesn't/ depend on the arg type.  It depends on the static<br>declarations.  That's not the same thing.  </pre>
                        </blockquote>
The result from "IsaT1( x)" DOES very much "depend on arg type."  There's
no other way to say it or think of it.  The trick is that the language is
designed so that the compiler knows at compile time what the object type
always will be.  Think of it as an optimization, where a runtime symbol table
lookup is replaced by a direct call to the proper function.  <br>
                        <br>
OOP with zero runtime overhead -- this is a FEATURE not a gimmick.
                        <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                          <pre wrap="">Try this:<br><br>  class A {};<br>  class B : public A {};<br>  class C : public A {};<br><br>  int isaB(A x) {return 0;}<br>  int isaB(B x) {return 1;}<br><br>  int buggy(A x) {return isaB(x);}<br><br>now create a B instance and C instance and try calling isaB() on<br>them.  That works OK.  Call buggy() on them.  That fails.</pre>
                          </blockquote>
It doesn't  "fail".  It merely does not do what YOU want it to do.  <br>
                          <br>
Buggy() by definition only works on objects of type A.  In all calls to buggy
C++ coerces sub-types of A to type A.  Since x can never be anything but
type A, the test can never be true.  A global optimizing compiler would convert
it to "return 0".<br>
                          <br>
Again, this is a feature.<br>
                          <br>
I can see how, if the bulk of your OOP experience was with a late binding
language like Lisp, then this behavior would seem foreign.  But for those
of us who's background is primarily with early binding languages, it makes
sense.<br>
                          <br>
In this case, right or wrong is very much a relative term and depends on
your background and perspective.<br>
                          <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                            <pre wrap="">Feel free to rewrite it with pointers, if you still believe that will<br>help.  It won't.  [And you can't even fix that with "virtual"]</pre>
                            </blockquote>
You are right that virtual does not apply.  However, there is nothing to
"fix".  Function overloading is a form of Polymorphism that does not involve
Objects.  Perfectly legitimate per the various 3rd party authorities above.<br>
                            <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                              <pre wrap="">That's the difference between C++ overloading and proper multiple<br>dispatch, as in Lisp.  Overloading is just a syntactic hack [...]<br>no different than writing [...]<br>different names for each overloaded definition.</pre>
                              </blockquote>
Partly true (in the case of regular functions) except the user doesn't have
to make up the goofy names.  This is a significant feature.<br>
                              <br>
However, overloading also applies to operators such as + and *.  In this
case there is NO WAY to make up different names and get the same effect.
 It's Polymorphism in it's basic form -- the same method works differently
when applied to objects of different types. <br>
                              <br>
The operators emphasizes why this aspect of C++ OOP is an extension over
Python.  In C++ you can define + and * for vectors and also a version with
scalar arguments.  No way to do that with Python.  Optional arguments gives
you a small subset of that capability but falls flat for some other applications.<br>
                              <br>
OOP doesn't always have to be implemented the way YOU happen to be used to.
 It doesn't have to be a runtime phenomenon to be legitimate, let alone useful.<br>
                              <br>
How is "proper multiple dispatch" any better?<br>
                              <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                                <blockquote type="cite">
                                  <pre wrap="">In Python you're hosed as there is no way to<br>discriminate class functions by argument signature.  I hope that eventually changes.<br></pre>
                                  </blockquote>
                                  <pre wrap=""><!---->I hope it doesn't.  At least, not unless it changes toward multiple<br>dispatch (which is unlikely).</pre>
                                  </blockquote>
Independently of implementation, I am describing a missing feature that I
think it would be very nice to have.<br>
                                  <br>
Python being a late binding language, it probably would do the final function
selection at runtime just like in LISP.  How would that differ from 'multiple
dispatch'?  
                                  <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                                    <pre wrap="">Yes.  Just like Python's dict.  [In fact, if you have a quick look at<br>the Python source code, you'll find that most of the built-in<br>functions are in fact implemented by having pointers at fixed<br>locations in the C struct that represents the class, too!]</pre>
                                    </blockquote>
I did not know that.  <br>
                                    <br>
Then I would then say Python is using "early binding" for the built-ins.
 ;o)  <br>
                                    <br>
And that it's smart and shows the value of early binding. ;o)<br>
                                    <br>
I mean, this case is completely different from C++'s virtual functions, right?
There's no decision at runtime based on object type, right?  Just a static
table in partial recognition of the sometimes intolerable cost of looking
up each name at runtime.  <br>
                                    <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz">
                                      <pre wrap="">It's important that you use the same definitions as<br>everybody else, not just make up your own as you're doing here.</pre>
                                      </blockquote>
That might be a fair criticism EXCEPT for the fact that *I* defined my terms
last week at the start of this branch of the discussion.  If you want to
go back and argue the original definitions, that's one thing.  But you're
out of line to accuse ME of being arbitrary when I clearly defined the terms
up front.<br>
                                      <br>
Clearly you're one of those zealots who believes that "late binding" is an
essential ingredient in Polymorphism and in OOP generally.  I disagree and
think I've made my point.  "We'll let the viewers decide."  In any case I
am too exhausted with the subject to continue (unless something REALLY juicy
comes up).  <br>
                                      <br>
However, I would like to hear more about why multiple dispatch is so special.<br>
                                      <br>
You and I have had civil exchanges in the past.  I hope we can agree to disagree
in this case without anybody getting their nose bent out of joint.<br>
                                      <br>
Regards<br>
                                      <br>
--jb
                                      <blockquote type="cite" cite="mid:m2adnddj3b.fsf@mycroft.actrix.gen.nz"></blockquote>
                                        <pre class="moz-signature" cols="$mailwrapcol">-- 
James J. Besemer                503-280-0838 voice
2727 NE Skidmore St.            503-280-0375 fax
Portland, Oregon 97211-6557     <a class="moz-txt-link-freetext" href="mailto:jb@cascade-sys.com">mailto:jb@cascade-sys.com</a>
                                <a class="moz-txt-link-freetext" href="http://cascade-sys.com">http://cascade-sys.com</a>       
</pre>
                                        <br>
                                        </body>
                                        </html>