James Strachan | 23 Feb 12:31 2005

Re: support of Java style arrays; or using Groovy arrays?

Agreed with all that.

I'm tempted to say that for now coercions should be explicit (via 'as' or static type declarations) - to
avoid falling into these kinds of holes.

So if I have a list and wanna call a method which takes a LinkedList, I should explicitly coerce.
 Its not that hard to do; then we could consider later on adding more cases of auto-coerce when we're really
happy it doesn't open the door to confusing behaviour.

Do we think auto-coercing lists and arrays might cause confusion? It does seem the most common use case we
should consider allowing (though for now I'd be happy to punt if we're not sure).


On Wednesday, February 23, 2005, at 10:31AM, John Rose <rose00@...> wrote:
>On Feb 22, 2005, at 23:30, jastrachan@... wrote:
>>> To close the loop, there should also be some Groovy story about 
>>> converting arrays (from those Java APIs) back to lists, maybe 
>>> implicitly.
>> Yes. I'm thinking that lists and arrays should happily coerce into 
>> each other.
>> int[] x = [1, 2, 3]
>> List y = x
>> I wonder if that should also mean that we can invoke methods with 
>> lists/arrays interchangeably?
>Yes, the differences between arrays and lists will be small, and 
>happily ignorable in many cases.
>> def foo(String[] whatnot) {
>>     println whatnot.length
>> }
>> def list = [1, 2, 3]
>> foo(list)
>Yes, this is very convenient.  Potential confusion around the edge 
>cases (there's always some) is limited, I think.
>There will be occasional gotchas, when an argument array is used not 
>merely "by value" but significantly "by reference".
>Arrays.sort([3,1,2] as int[]) will reorder values into a temporary 
>array and then throw it away, a useless and buggy exercise.
>A Java method might use a one-element array to pass back a second 
>return value.  Etc.
>But on balance, I think that most Java APIs, when they use arrays, use 
>them by value.  (I.e., they represent tuples, and side effects are 
>The java.util.Arrays utilities are a big exception, but it's an obvious 
>one to look out for.
>Thus, the Groovy conversion from a List to a Java array (via toArray) 
>merely snapshots the values of the List, into a commonly used form.
>> BTW was chatting with Dion the other day and he came up with a 
>> requirement for creating lists & maps using another implementation; 
>> e.g. a LinkedList. His idea was to use the same coercion...
>> def z = [1, 2, 3] as LinkedList
>Or, equivalently (as we've been saying):
>	LinkedList z = [1, 2, 3]
>> which could be a neat way to specify the exact list/map implementation 
>> to use? Again like the list->array coercion, the list->concrete list 
>> implementation coercion is easy to catch in the AST to do the right 
>> thing efficiently.
>The Java collection classes use one-argument constructors to express 
>such format-changing conversions, as {new LinkedList(myOldList)}.
>It seems natural to support many of those as explicit conversions.  I 
>suspect it may be going too far to support them as implicit 
>The thing to be suspicious of (IMO) is a chain of implicit conversions 
>that reformats a stateful object into a another similar stateful 
>The two objects would have similar contents, but there would be two 
>independent object states, an original and a sort of clone.
>That might cause bugs where the user thinks the original object is 
>present, but changes intended for the original are applied to the clone 
>	def myList = [3,1,2]
>	SomebodysUtilities.sortLinkedList(myList)  // but the method 
>implicitly converts to LinkedList!
>	assert myList == [1,2,3]  // Fails!
>For Groovy, perhaps the way to control this is to allow implicit 
>conversions to lose statefulness, but not to create it (with arrays 
>serving as honorary tuples).
>A simple example of this principle:  Let a List convert to a boolean 
>via '!isEmpty', but don't convert from a boolean back to a List.
>Another observation:  Some coercing constructs like 'as' expressions 
>and variable declarations manifest both the target type and the source 
>expression, and thus make it clear that a conversion is taking place, 
>and what the target type is.
>Others don't, such as method calls.
>Coercions in method calls are trickier and potentially buggier, because 
>the target type and source expression are often mentioned in separate 
>files; there's more potential for surprise.
>Perhaps the LinkedList conversion should be not be supported as part of 
>a method call, without an explicit 'as' expression.
>-- John
>P.S.  I've sometimes thought that a conversion-rich language (not 
>necessarily Groovy) should have two categories of conversion, a 
>reference conversion which preserves stateful identity, and a value 
>conversion which preserves current value.  (For stateless objects, like 
>primitives and strings, the two notions collapse into one.)
>Reference conversions could go beyond Java to include "view-building" 
>operations like Arrays.asList, but not "content-sampling" operations 
>like List.toArray.