I've re-read an old (1997-2000) article about Java. The author seems an expert 
lisper. Of course some of those comments about Java are obsolete today:
http://www.jwz.org/doc/java.html

I don't remember if I have already shown this article here, I have found only 
this, from 2001:
http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=1319


Some quotations from the article. Some of the following things apply to D too 
(probably as seen from a CLisp programmer). My few comments are in []:

The fact that static methods aren't really class methods (they're actually 
global functions: you can't override them in a subclass) is pretty dumb.

This "integers aren't objects" nonsense really pisses me off. Why did they do 
that? Is the answer as lame as, "we wanted the 'int' type to be 32 bits instead 
of 31"? (You only really need one bit of type on the pointer if you don't need 
small conses, after all.)
[In D you are able to define such single-word integers in library code, but 
they are not the default integer type.]

After all this time, people still think that integer overflow is better than 
degrading to bignums, or raising an exception?
[Of course not. Maybe D devs will get there.]

I sure miss multi-dispatch. (The CLOS notion of doing method lookup based on 
the types of all of the arguments, rather than just on the type of the implicit 
zero'th argument, this).
[Andrei may Ask some CLisp programmers why they like multi-dispatch and what 
they use it for.]

The finalization system is lame. Worse than merely being lame, they brag about 
how lame it is! To paraphrase the docs: "Your object will only be finalized 
once, even if it's resurrected in finalization! Isn't that grand?!" Post-mortem 
finalization was figured out years ago and works well. Too bad Sun doesn't know 
that.
[I think this is getting fixed in D2]

Relatedly, there are no "weak pointers." Without weak pointers and a working 
finalization system, you can't implement a decent caching mechanism for, e.g., 
a communication framework that maintains proxies to objects on other machines, 
and likewise keeps track of other machines' references to your objects.
[Weak pointers will eventually be present in Phobos]

The locking model is broken.

    First, they impose a full word of overhead on each and every object, just 
in case someone somewhere sometime wants to grab a lock on that object. What, 
you say that you know that nobody outside of your code will ever get a pointer 
to this object, and that you do your locking elsewhere, and you have a zillion 
of these objects so you'd like them to take up as little memory as possible? 
Sorry. You're screwed.
    [I have not yet understood why D shared this Java design choice.]

    Any piece of code can assert a lock on an object and then never un-lock it, 
causing deadlocks. This is a gaping security hole for denial-of-service attacks.

    In any half-way-rational design, the lock associated with an object would 
be treated just like any other slot, and only methods statically "belonging" to 
that class could frob it.


There is no way to signal without throwing: that is, there is no way to signal 
an exceptional condition, and have some condition handler tell you "go ahead 
and proceed anyway." By the time the condition handler is run, the excepting 
scope has already been exited.

The distinction between slots and methods is stupid. Doing foo.x should be 
defined to be equivalent to foo.x(), with lexical magic for "foo.x = ..." 
assignment. Compilers should be trivially able to inline zero-argument accessor 
methods to be inline object+offset loads. That way programmers wouldn't break 
every single one of their callers when they happen to change the internal 
implementation of something from something which happened to be a "slot" to 
something with slightly more complicated behavior.
[This is fixed/done in Scala language]

The notion of methods "belonging" to classes is lame. Anybody anytime should be 
allowed to defined new, non-conflicting methods on any class (without 
overriding existing methods.) This causes no abstraction-breakage, since code 
which cares couldn't, by definition, be calling the new, "externally-defined" 
methods. This is just another way of saying that the pseudo-Smalltalk object 
model loses and that generic functions (suitably constrained by the 
no-external-overrides rule) win.
[This last idea looks like C# extension methods]

Bye,
bearophile

Reply via email to