list literal gotcha and suggestion

Neal Gafter neal at gafter.com
Tue Oct 6 07:45:54 PDT 2009


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