Sdk: Support a Set literal syntax

Created on 20 Jun 2012  路  20Comments  路  Source: dart-lang/sdk

Sets are very helpful, it would be nice to have a set literal syntax (like the [] for lists and {} for maps) for more terse code.

area-language core-a type-enhancement

Most helpful comment

I propose the curly bracket syntax for sets -- just same as maps. The only difference would be that brackes would contain particular elements instead of key-value pairs like this:

Set<String> fruits = {'apple', 'banana', orange};

Is It seems logical in many ways:

  • Both map keys and set elements are uniqe. Set is like map of keys with no values.
  • It corresponds with mathematical sets, which are denoted with curly braces as well.

All 20 comments

_Set owner to @gbracha._
_Added this to the Later milestone._
_Added Accepted label._

_This comment was originally written by @seaneagan_


another reason: without this there is no way to create a "const" Set, so you are forced to use a List when you need a constant.

I have run up against this problem also, and have wanted a const Set. I have used a map with null values instead.

_This comment was originally written by rasmu...@sonardesign.com_


without this there is no way to create a "const" Set

Yep, I just ran into this as well.

There is a workaround however, better than using a List, I think:

    static final Set<String> units = new Set<String>.from(['em','pt','px','%']);

Be careful exposing a normal set directly, as it's mutable.

Consider UnmodifiableSetView
https://api.dartlang.org/apidocs/channels/stable/#collection/dart-pkg-collection.UnmodifiableSetView

This is where having literal syntax + const would be great.

_This comment was originally written by rasmu...@sonardesign.com_


In my case it's package-internal, so I'm no concerned.

_Removed this from the Later milestone._
_Added Oldschool-Milestone-Later label._

_Removed Oldschool-Milestone-Later label._

See issue #174. This is almost a duplicate,e xcept I am not yet convinced that a const set requires literal set syntax.

_This comment was originally written by @kaendfinger_


If this were to come, I was thinking a prefix to the list literal:

const Set<String> strings = @­[
  "A",
  "B"
];

Prefixes that would maybe work would be: %, :, and ~

The @­ prefix was just a demonstration, I don't recommend that one because of annotations (metadata).

_This comment was originally written by @kaendfinger_


Oops, add a const in front of the list literal in the above comment's example.

I propose the curly bracket syntax for sets -- just same as maps. The only difference would be that brackes would contain particular elements instead of key-value pairs like this:

Set<String> fruits = {'apple', 'banana', orange};

Is It seems logical in many ways:

  • Both map keys and set elements are uniqe. Set is like map of keys with no values.
  • It corresponds with mathematical sets, which are denoted with curly braces as well.

:+1:

@VanNiewelt

It corresponds with mathematical sets, which are denoted with curly braces as well

. :+1:

I propose the curly bracket syntax for sets -- just same as maps.

One problem with that is, how you define an empty set? {} is already a map. Python simply says there is no syntax for an empty set literal, but that's kind of sad.

EDN (Clojure data format https://github.com/edn-format/edn) uses this syntax #{1 2 3}

It would also be cool if .add and .addAll would return a Set for better chaining

I wonder if in most cases we could infer whether {} is a Map or Set.

Side note:
@allumbra, there is no need for add and addAll to return the receiver because Dart has a built in chaining feature called cascades:

print(new Set<int>()..add(1)..add(2)..addAll([2, 3]));  // prints {1, 2, 3}

Since chaining does not 'use up' the return value, the return value can be something useful. Set.add returns true when the item was added, allowing you to write

if (items.add(item)) {
   print('Yay, a different item');
}

All non-empty set literals would be distinguishable from map literals, as would any set literal with a type argument. The only tricky case is the {} literal which has no elements/entries and no type argument.
It's probably possible to infer that it's an empty Set if the surrounding context wants it to be a Set, and default to Map otherwise.
We already plan to infer the type of integer literals in a double context, and I think inferring types for ambiguous literals, or other expressions, from the context is reasonable in general, at least as long as there is always a non-ambiguous syntax that you can write instead if you want to be sure.

Updated issue with links to more proposals: https://github.com/dart-lang/language/issues/36

Was this page helpful?
0 / 5 - 0 ratings