Lies. Java is intrinsically verbose. Say I want to make a class with
a read-only attribute "Foo".<p>CLOS:<p><pre><code> (defclass class () ((foo :reader get-foo :initarg :foo)))
</code></pre>
Moose:<p><pre><code> class Class {
has 'foo' => ( is => 'ro' );
}
</code></pre>
Java:<p><pre><code> class Class {
private String foo;
public Class(String foo) { // named initargs are clearly for losers
this.foo = foo;
}
};
</code></pre>
Notice how a common high-level task requires a manual error-prone
implementation, every single time. Java provides only the concepts of
"class", "field" and "constructor", while the other languages provide
the high-level concept of an "attribute", which is what the programmer
actually wants. (The first concept is easy for the language
implementor, the second concept is easy for the practicing
programmer.)<p>I should also point out how the verbosity exists only for the sake of
being verbose, not for creating more reliable software. Perl and CLOS
assume I want named initargs, making use of my class self-documenting:<p><pre><code> (make-instance 'class :foo 42 :bar 123)
Class->new( foo => 42, bar => 123)
</code></pre>
That's verbose, but it makes the code very easy to read and write. No
guessing about what slot is being set to what value.<p>With Java, though, it's anyone's guess as to what's going on:<p><pre><code> new Class(42, 123);
</code></pre>
The only way to know which field gets set to which value is to Read The Fine Source:<p><pre><code> public Class(int bar, int foo){
this.foo = bar;
this.bar = foo;
System.Utils.delete_users_pr0n_stash();
}
</code></pre>
foo does get set to 42, but only by accident... and there are unexpected side effects.<p>So much less typing though! <i>cough</i>.<p>Another common programming pattern is reusing code. (I hear people
like doing that.) Say you have classes representing numbers, and you
want to add a "not equals" method to each type. That's easy, you can
just write a generic role like:<p><pre><code> role Eq {
requires 'equal';
method not_equal($a: $b){
return !$a->equal($b);
}
}
</code></pre>
Then I can easily reuse that extremely-complex "not_equal" method:<p><pre><code> class Int with Eq {
has value => ( is => 'ro', required => 1 );
method equals($a: $b){
return $a->value == $b->value;
}
}
Int->new( value => 42 )->not_equals( Int->new( value => 123 ) ); # True
</code></pre>
In Java, I can still maintain a similar interface:<p><pre><code> interface Eq {
public bool equal(Eq that); // Eq is not really the type I want, but whatever.
public bool not_equal(Eq that);
}
</code></pre>
But the implementation can't be shared:<p><pre><code> class Int implements Eq {
private int value;
public Int(int value){ // didn't we just say "int value" like one line ago?
this.value = value;
}
public bool equal(Int that){
return this.value == that.value;
}
public bool not_equal(Int that){
return !this.equal(that);
}
}
</code></pre>
This is both verbose and error-prone. (I will also point out that
Java calls Eq "Comparable" and uses the "implements" keyword instead
of "with". But this is petty. I'm surprised they were happy with
"implements" and didn't choose the clearer expression
"implementsTheInterfaceThatIAmAboutToTypeRightAfterIAmDoneTypingThis".
Your editor can type that for you, after all...)<p>But wait, we can use the strategy pattern to save us!<p><pre><code> class NotEqualStrategy {
public bool not_equal(Eq a, Eq b){
return !a.equal(b);
}
}
class Int {
private NotEqualStrategy not_equal_strategy;
private value;
public Int(NotEqualStrategy nes, int value){
this.not_equal_strategy = new;
this.value = value;
}
public bool equal(Int that){
return this.value == that.value;
}
public bool not_equal(Int that){
return not_equal_strategy.not_equal(this, that);
}
}
</code></pre>
At least I don't have to cut-n-paste the logic anymore, but it's still
very verbose. Imagine you had to delegate more than one method -- you
can do it, but it involves a ton of meaningless code.<p>In Perl, I can just say:<p><pre><code> class NotEqualsStrategy {
method not_equal(Eq $a, Eq $b){
return !$a->equal($b);
}
}
class Int {
has 'not_equals_strategy' => (
is => 'ro',
isa => 'NotEqualStrategy',
required => 1,
handles => ['not_equal'],
);
has 'value' => ( is => 'ro' );
method equal(Int $a: Int $b){
$a->value == $b->value;
}
}
</code></pre>
Notice how I didn't have to type the cut-n-paste delegation; the
language did it for me. I didn't have to type it, I don't have to
look at it, and I can't accidentally fuck it up. That's what
programming languages are supposed to do for you, and that's what Java
doesn't do.<p>In conclusion, Java is verbose, and verbosity is harmful.