list literal gotcha and suggestion

Reinier Zwitserloot reinier at zwitserloot.com
Tue Oct 6 03:11:41 PDT 2009


We went over this - target typing is asking for problems. If you can  
shed any light on how VB.net gets around these problems, perhaps we  
can reconsider it, but if not, I don't see how this changes the  
situation any.

Some example questions that highlight why VB's system is no good:

public String test() {
     return {{1, "Apple"}, {2, "Orange"}}.toString();
}

should this return [[1, "Apple"], [2, "Orange"]] or should it return  
{1: "Apple", 2: "Orange"} (that is: Should it build a list of list of  
object and toString that, or should it build a map of Integer to  
String, and toString that)?


public void test(Object... args) {
     System.out.println(args.getClass().getSimpleName());
}

public void test2() {
     test({1, 2, 3});
}


should this print: 'int[]', 'Integer[]', 'int[][]', or 'List[]'?


These examples all look nice when you assign them to a properly typed  
variable. The moment you remove that Left-hand-side type context,  
these kinds of solutions tend to suck (in that it becomes a small  
nightmare to figure out, from a casual glance, what it is that you're  
looking at. List? Set? Array? Map?) I suggest that the only practical  
way to make target typing work is to make these literals illegal  
unless they are being used as the expression in a variable assignment  
expression or variable declaration statement. However, one of the main  
benefits of having literals is that you can inline a list literal with  
a few elements directly into a method call, which you'd obviously lose  
if you tack on this requirement. It helps to remember that java's  
method overloading makes any sort of target typing based on position  
in method argument list no more than a rough guestimate.

  --Reinier Zwitserloot



On 2009/06/10, at 07:44, Paul Benedict wrote:

> I received my latest MSDN magazine yesterday, and it brought back my
> memories of my (very in the past) Visual Basic days. One article
> displayed their latest integration with .NET collections. Here are
> some excerpts:
>
> Dim aList As New List(Of Integer) = { 1, 2 };
> Dim aArray = { 1, 2, 3 };
> Dim aMap As New Dictionary(Of Integer, String) From {{1, "Apple"}, {2,
> "Orange"}};
>
> It was interesting to see a uniform initialization syntax. No need for
> switching symbols to indicate type. Java could do the same since { }
> already means initializations for array literals. Someone may want to
> think about why Java arrays are initialized with { } but Java lists
> would be initialized with [ ]. Sorry, but that isn't consistent.
>
> Here's a short summary of the good alternatives recently mailed:
>
> by Nick Parlante:
> List<Integer> piDigits = { 3, 1, 4, 1, 5, 9, 2, 6, 5 };
> Set<Integer> primes = [ 2, 7, 31, 127, 8191, 131071 ];
> "or if that [set literals] causes problems, just don't have a literal
> for sets. Lists and maps are the most common, so having a syntax for
> those cases is the most important."
>
> by Greg Brown:
> List<Integer> list = ArrayList.unmodifiableList(1, 2, 3);
> Set<String> set = HashSet.unmodifiableSet("a", "b", "c");
>
> by Reinier Zwitserloot
> new HashSet<>(["a", "b", "c"]);
> List.of("a", "b", "c");
>
> by Stephen Colebourne:
> Set<String> set1 = HashSet.of("1", "2", "3");
> Set<String> set2 = {1, 2, 3}.toSet();
> SortedSet<String> set = {1, 2, 3}.toSortedSet();
> MultiSet<String> mset = {1, 2, 3}.toMultiSet();
> List<String> list1 = ArrayList.of("1", "2", "3");
> List<String> list2 = {"1", "2", "3"};
> Map<Integer, String> map1 = {1 : "1", 2 : "2", 3 : "3"};
>
> by Neal Gafter:
> "I agree that a solution along these lines [map key:value pair] is a
> better approach for these literals.  However, I don't think the binary
> ":" operator is the best way to
> introduce a pair literal.  Besides the ambiguity in the second
> position of a ?: expression (which can be resolved by precedence),
> this conflicts with the most likely syntax for named parameters*."
>
> by Jonathan Gibbons:
> "We could also use JSR 308 annotations to achieve some amount of
> compile time checking of varargs argument lists."
> class HashSet {
> static HashSet<T> of(@Unique T...)
> }
>
> by Florian Weimer:
> Map<String, Integer> map = new HashMap<String, Integer>() {{
>    put("a", 0);
>    put("b", 1);
>    put("c", 2);
> }};
>
> by John Hendrikx:
> "Maps however would remain a pain to instantiate.  So a good syntax
> for creating maps or more generally, pairs or groups of values would
> alleviate that.  Personally I was thinking more along the lines of
> providing a constructor like this for Maps:
>    public HashMap(Pair<K, V>... pairs);
> With some new syntax to easily create Pairs:
>    Pair<Integer, String> p = {1: "A"};
> Resulting in:
>    new HashMap<Integer, String>({1: "A"}, {2: "B"}, {3: "C"});"
>
> Paul
>




More information about the coin-dev mailing list