22 Feb 2005 11:30
support of Java style arrays; or using Groovy arrays?
Even in Classic Groovy we've never really been able to properly support
Java style arrays. e.g. Java supports the following syntax for variable
declarations
int[] x = {1, 2, 3}
which is not supported in any Groovy version, and cannot really be
supported as its ambiguous with closures. Even if we did support the
above, it'd be a bit weird in non-static type situations as well as not
being usable as an expression
def x = {1} // closure or array?
methodCall( {1 } ) // closure or array?
So this kind of array initialiser is not very easy to support and even
if we did, its not very consistent and has limited use. A much more
groovy way would be
int[] x = [1, 2, 3]
the nice thing about this is the right hand side expression is
definitely, clearly groovy and can be used in other circumstances too
def x = [1, 2, 3]
methodCall( [1, 2, 3] )
We could also go one step further; allowing any list expression to be
easily coerced into an array...
int[] n = [1, 2, 3]
Cheese[] x = list.collect { it.foo }
In dynamic typing mode the following actually makes a list...
def x = [1, 2, 3]
so to mimic the above at the expression level we can use the coercion
mechanism
def x = [1, 2, 3] as Integer[]
methodCall( [1 , 2 3] as int[] )
The nice thing about the above is that this provides a simple and
consistent way to convert lists to arrays either via typesafe variables
or using the 'as' coercion mechanism - also the mechanism is the same
whether the expression is statically or dynamically typed and whether
the array contents are specified exactly at compile time (like the Java
versions) or whether they are programmatically generated, such as by
the result of a findAll() or collect() method.
e.g.
Customer[] customers = customerList.findAll { it.name.endsWith("s") }
def customers = customerList.findAll { it.name.endsWith("s") } as
Customer[]
So Java has 2 array expressions...
String[] x = {1, 2, 3}
or
new String[] { 1, 2, 3 }
Now we can never fully implement the old style Java array initialiser,
as discussed above; but we could consider supporting the 'new [] { ...
}' clause though.
The plus side of supporting half-of the Java array initialiser is that
* we keep a bit more Java heritage and avoid some possible confusion
The downside of supporting half-of the Java array initialiser is that
* we don't fully support the array initialiser and so could cause some
possible confusion
* the new[] { ... } syntax can only be used to create a static array;
we cannot use a list expression to create the array (such as the
collect() method example at the top of the mail) so its of limited use;
indeed we'll end up with 2 ways of making an array - one the Java way
and one the groovy way
* it uses {} which opens the door to ambiguity - we've been really
careful to avoid using {} in the language other than for blocks and
closures - indeed many languages use {} for maps but we overloaded []
to avoid confusion
On balance I think I favour not supporting the old Java array syntax
and just supporting the groovier alternative
Integer[] x = [1, 2, 3]
def x = [1, 2, 3] as int[]
methodCall( [1, 2, 3] as Integer[] )
Customer[] customers = collection.findAll { it.location == 'UK }
which is much simpler, easier to learn, is quite intuitive once you've
learnt lists and is much more consistent - working for static & dynamic
expressions for the contents, and working the same in both static and
dynamically typed contexts.
The added bonus is that the language ends up being smaller (we have no
special array initialiser syntax) and we have much less possibilities
of ambiguity with arrays and constructors/blocks/closures/inner
classes.
A new user to Groovy might find groovy arrays a bit surprising at
first; but you could argue that making arrays much more like lists is
less surprising than having various wildly different constructs for
lists and arrays depending on the static/dynamic array construction and
static/dynamic typing.
Thoughts?
James
-------
http://radio.weblogs.com/0112098/
RSS Feed