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