list literal gotcha and suggestion

Neal Gafter neal at gafter.com
Tue Oct 6 10:36:21 PDT 2009


It hasn't been introduced yet.  I'd call the type "an initializer list".
The (compile-time) conversion rules describing what conversions are allowed
and which are not allowed would be written in terms of the values of the
initializers.

These types need not exist at runtime, nor need there be any way of naming
them in the source or declaring objects of these types.  This is the
approach currently used in the language to allow, for example, 3 to be
assigned to a variable of type byte (even though 3 is of type int and you
can't assign an int to a byte).

On Tue, Oct 6, 2009 at 8:59 AM, Reinier Zwitserloot <reinier at zwitserloot.com
> wrote:

> 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