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

Fw: Beyond Java?




----- Original Message -----
From: Scott McKay <swm@mediaone.net>
To: <M.Kizub@post.skynet.lt>; <swm@functionalobjects.com>;
<jason@functionalobjects.com>
Sent: Monday, March 05, 2001 2:17 PM
Subject: Re: Beyond Java?


> With all due respect, I think you are making some assumptions that
> cause some of your conclusions to be incorrect.  In particular, you
> don't credit good compilation techniques nearly enough.  More below.
>
> -----Original Message-----
> >>Date: Sun, 4 Mar 2001 20:22:35 +0100
> >>From: Maxim Kizub <M.Kizub@post.skynet.lt>
> >>Subject: Beyond Java?
> >>
> >>-----BEGIN PGP SIGNED MESSAGE-----
> >>Hash: SHA1
> >>
> >>=============================
> >>Dear Dr Jason Trenouth
> >>
> >>I read your article "Beyond Java?" and I disagree
> >>with you. Let me explain:
> >>
> >>1) Single Implementation Inheritance
> >>
> >>The single inheritance is not a bad choice.
> >>It's, IMHO, a very wise choice - because
> >>java creators choosed to use virtual table
> >>method dispatching, and those 'solutions'
> >>for multiple inheritance that we see in C++
> >>only shows that multiple inheritance is a BAD
> >>thing.
>
> I'm afraid this resorts to the tired argument, "C++ did a terrible
> job, so it must be a bad idea".  Well, C++ did a terrible job of almost
> everything -- as we now know -- and we know that not everything it
> did is a bad idea.
>
> The problem in this case is that C++ chose too simple a way of doing
> method dispatching -- virtual tables -- and then tried to cram multiple
> inheritance in, without thinking about such things as ordering classes
> into what CLOS calls a "class precedence list".  When you build
> method dispatch on top of a properly defined class precedence list,
> things work out well.  There are lots of papers on CLOS and the CLOS
> meta-object protocol the describe this.  Dylan took this work, and
> did a stripped-down version.
>
> By the way, I won't lie to you -- writing clear code with good modularity
> in the face of multiple inheritance requires discipline and practice.
> But on the other hand, writing clear code with delegation or templates
> also requires discipline and practice.
>
> >>Anyway, I agree that multiple inheritance is
> >>sometimes a convinient technique, but it (usually)
> >>may be solved by others approaches. For example,
> >>allowing methods of interface be 'default'
> >>implementation of functions for classes that
> >>implements this interface, but do not define
> >>those functions. Another example - delegation.
> >>And note - both of these techniques do not require
> >>method dispatching by messages - and, thus, are
> >>about as fast as virtual methods calls.
>
>
> I'm afraid that delegation can be a very poor solution sometimes,
> because you lose track of the 'this' object.  Keeping track of
> 'this' requires maintaining a bit of state, either by having a 'this'
> field in all your classes or by passing a 'this' argument around
> in all your functions.  More important, breaking something into
> a delegation style when the natural relationship is "is-a" means
> that the code does not reflect the "real-world" design; this
> abstraction mis-match is what all good designs try to avoid,
> so having such a mis-match forced on you by the language is
> not a good thing.
>
> Having default implementations works poorly in Java because
> it means you *must* subclass in order to share.  And if there
> are not default implementations, you have to copy code, which
> is a maintenance nightmare.
>
> >>
> >>2) Single Argument Method Dispatch
> >>
> >>All your arguments are correct, but you do not
> >>mentioned one issue - single argument dispatching
> >>(that can be done with virtual table) are FAST,
> >>while multiple-argument dispatching is SLOW.
> >>VERY SLOW.
> >>And all your arguments costs nothing, if developer
> >>needs fast execution - if in normal situation
> >>only a few methods in the whole program really
> >>needs multiple-argument dispatching - your solution
> >>to dispatch _all_ calls in this way is unacceptable
> >>in most situation.
>
>
> This is one of the places where you don't give the compiler
> enough credit.  When there is adequate type information --
> as there always is in Java, and there usually is in Dylan when
> you use type declarations (and when the compiler can do
> good type inference) -- multi-arg dispatching is as efficient
> as compile-time overloading.  (Note that I did not say "almost
> as efficient" -- that's because it is *exactly* as efficient.)  In
> fact, Ken Anderson at BBN Labs did some very careful
> studies of multi-method dispatch compared to "staged single
> dispatch" and discovered that even in Lisp -- with no type
> declarations! -- multi-method dispatch was *more* efficient.
> Why?, you might ask.  Because the dispatch engine was
> highly tuned, and managed to get better use of machine
> resources such as registers.
>
> All the extant Dylan compilers get compilation of multi-methods
> right, BTW.
>
> If you use the optimization code-coloring feature in Fun-O's Dylan
> compiler, you will see that the open-source code supplied in
> FD manages to get its method calls statically dispatched about
> 85% to 90% of the time, which is pretty darned good.  In fact,
> there are some polymorphic benchmarks we did that managed
> to get static dispatch 100% of the time.
>
> >>
> >>3) Primitive Types Distinct From Objects
> >>
> >>The same as above. Primitive types are FAST and
> >>requires no additional memory allocation.
>
>
> Again, you are assuming a stupid compiler.  All the current Dylan
> compilers do good boxing/unboxing optimizations in  the face of
> sufficient type information, thus causing all important good to
> effectively use "primitive" types.  This means that you don't need
> to store any extra information, except when you are storing
> something in the heap and have not used any declared type.
>
> BTW, what I said above applies equally to C#, which removed
> the primitive types, and introduced explicit box/unbox operators.
> This is a little clunky, but it gets the semantics right.
>
> One more thing -- I think you are actually wrong about the relative
> efficiency of primitive types in Java, at least in practice.  The
> reason is that some "aggregate" types can only store things that
> are instances of classes.  Consequently, in real-world Java code,
> you tend to see an awful lot of calls to 'new Integer(x)' just to be
> able to store an 'int'.  Once you do that, "fast" goes right out the
> window.  (You might say that you don't do this, but I can assure
> you that the dozen Java hackers I work with now do this *all the
> time*, and it's claimed that most of them are good Java hackers.)
>
> >>
> >>4) Casting Required
> >>
> >>I agree, it's a problem. Even if java will have
> >>parametriezed types in future - I do not belive
> >>they will solve the problem.
> >>
> >>5) No Extensible Syntax
> >>
> >>Again, I agree with you.
> >>
> >>6) Poor Iteration/Collection Integration
> >>
> >>This is the problem of initial language design.
> >>End situation is even wirse - Iterators are
> >>disaster in multithreaded environment.
> >>
>
>
>