Swift can infer array types:
let myArray = ["a", "b", "c", "d"]
Swift can infer dictionary types:
let myDictionary = ["key1": "value1", "key2": "value2"]
But what about sets?
let mySet = ["a", "b", "c", "d"] as Set // or let mySet: Set = ["a", "b", "c", "d"]
These johnny-come-lately collections offer no automatic inferencing. Don’t sets deserve love too?
Parentheses are already taken by tuples. Angle brackets are protocol/generic specific No one wants to type 《》. Face it. Sets are Swift’s Jan Brady collections.
Swift playgrounds use braces to show sets in the results sidebar:
But of course, braces mean closures:
And even if Swift could infer a set from comma-delineated braced items, should it?
let mySet = {"a", "b", "c", "d", "e"} // wrong, bad, wrong let mySet = {members | "a", "b", "c", "d", "e"} // nope
You could do a lot worse.
let mySet = ~1, 2, 3~ // The "mustache" delimiter let mySet = ¯\_(ツ)_/¯ 1,2,3, ¯\_(ツ)_/¯ let mySet = •< 1, 2, 3 >• // ...etc...
Even if there were a way to infer sets, Swift still wouldn’t be able to infer option sets, bags, ordered sets, ordered dictionaries, counted sets, fashionable totes, shopping satchels, and unique arrays.
let myTotes = [(Gucci, Prada, Louis Vuitton)]
You could try (or try! or try?) but you’re just (ahem) setting yourself up for failure.
So what should Swift do? You tell me.
Thank you everyone in #swift-lang IRC for your suggestions.
3 Comments
My first thought was Swift should use the vertical bar: |”a”, “b”, “c”|. The problem comes in with an empty set being the same as a logical OR. Maybe a vertical bar / square bracket combo: |[“a”, “b”, “c”]|?
You can use prefix (or postfix) operators that just return their input to get the type inference to recognise a set:
prefix operator | {}
public prefix func |
(x: Set) -> Set {
return x
}
let set = |[1, 2, 3]
But that’s probably a bad idea.
You’ve tacitly acknowledged that Set is ArrayLiteralConvertible; the generic type system infers the array literal’s Element type:
let stringSet: Set = [“a”, “b”, “c”]
// {“b”, “a”, “c”}
// Opt-click → let stringSet = Set
… so the issue is braces versus a type annotation that’s only _mostly_ inferred? You have to draw the line on syntactic sugar somewhere (Swift may already have more than is good for it), but I can respect the argument that Set should be common enough to earn its sugar.
Identifying a Set, as such, isn’t where the programmer’s cognitive load is. Inferring the Element type from a collection that may not be so obviously homogeneous, or may change Element type as the code is revised, is 90% of the work (weighted by the potential for programmer error). Next to that, I’ll pay the five characters (I’m on the colon-space team).
And I’ll be 60 in two weeks. Please don’t make it critical that I distinguish braces, brackets, and parentheses without context.