list literal gotcha and suggestion

Reinier Zwitserloot reinier at zwitserloot.com
Tue Oct 6 08:59:49 PDT 2009


Which newly introduced type is flexible enough to be capable of  
converting it self both to a List<List<Object>> and to a List<Integer,  
String> given: {{1, "one"}, {2, "two"}}?



On 2009/06/10, at 16:45, Neal Gafter wrote:

> The same effect can be had without target typing.  Essentially, one  
> defines the {}-literals in terms of a newly introduced type/class,  
> and then define compile-time conversions from that new type to each  
> of the types you want it to convert to.  Java's type inference, for  
> example (including constructor type inference), can be described  
> this way, and that's how it works inside the compiler.
>
> On Tue, Oct 6, 2009 at 3:11 AM, Reinier Zwitserloot <reinier at zwitserloot.com 
> > wrote:
> 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