Re: StringBuilder Difficulties
On 04/07/2011 3:45 PM, Robert Klemme wrote:
On 04.07.2011 16:52, Gene Wirchenko wrote:
It is horribly verbose. Java: COBOL++?
In part it's the price you pay for static typing
Wrong. Lots of strongly statically typed languages don't have nearly the
verbosity, including Haskell and the ML family of languages. Generally
what they have is very smart type inference capabilities in the
compilers, so you have to specify types quite rarely, e.g. specifying
the precision a literal number should be considered to have, and
specifying argument types to functions. In-function declarations and
sometimes return types are inferred by data flow analysis. A Java
equivalent would be if you could do
public foobar (int a, String b) {
x = a + b.length();
y = 1.3*x;
return y.toString();
}
and this would work, with the compiler first resolving .length() to
String's method and seeing that this returns int, seeing then that a
b.length() adds two ints so is of type int, and inferring x is an int;
then y is a double times an int so y is a double; then resolving
..toString(); to Double's method (post-autoboxing of y) and inferring
that foobar's return type is String.
pubic wontwork (int a, String ) {
x = a + b
}
blows up, meanwhile, because int + String is not defined anywhere.
In this case, x and y lack *manifest* typing but have compile-time types
more specific than Object.
The thing is, javac already does some type inference, and indeed decides
which .length() method is being called in line 1 and the type of the
expression a + b.length() in exactly the way described above. It just
won't go on to infer x's type if it's not specified. (Partly, also, the
absence of a type before x would make declaring and initializing a local
not look different from assigning to it. A nice rule would be that
mutable x = ...
declares and initializes a mutable local and
x = ...
declares and initializes an immutable local if no mutable x is within
scope, and assigns to the innermost in-scope mutable x otherwise. This
would favor less use of mutation and type inference would take much of
the pain out of any proposed syntax for lambdas in Java, making Java
more supportive of using a functional style in areas where that's
appropriate and avoiding some of the mutation "side-effect spaghetti
code" that's all too common these days.
The semantics above would be that if x isn't explicitly declared
"mutable", it acts like in current Java when it's declared "final".
Definite assignment rules would still apply, more-or-less unchanged,
with "mutable x;" being allowed as "int x;" is now and
if foo
x = baz;
else
quux.frobnicate();
return x + 3;
being a definite assignment violation if no local x existed above "if
foo" in that method body, a violation of finalness if a final x existed
above "if foo" in the same block, and OK if a mutable x existed above
"if foo" in the same scope and was definitely assigned to even if the
else clause executed (say because it was "mutable x = 0;" at the point
of declaration). An immutable x in a block enclosing the block but not
in the same block as the if would create a conundrum: depending on the
if branch taken there seem to be two different xs that the return could
mean. I'd say though that the x = baz; creates a local x in the directly
enclosing block that exists, but is not definitely assigned, at the
return statement. As for
x = foo;
mutable x = bar;
in the same block: illegal. But in nested blocks, inner shadows outer as
always.
Let me know if you find any obvious problem with the above ideas
(besides the high improbability that Oracle will ever implement them).
Tools are good enough these days to offload
you from most of the hand typing via completion.
A proof of concept that javac could do more of the type-inference heavy
lifting itself.
If you look for a language on the JVM with less overhead maybe Scala is
for you. Some people do find it too compact though.
Another functional language with type inference.
Define "too compact", given that it doesn't go to line-noisy extremes
like perl.