[Proposal] Set literal and Set type syntax

I agree that the probably isn't a better story for literals and Sets and
that I wish that there were a better story.

The best that I can think of is some sort of flag outside of the Array
literal, for instance, #["A", "B", "C"] or just using keys that people
aren't already accustomed to like option-'\' and option-shift-'\'. «"A",
"B", "C"]»

TJ

···

On Tue, Jan 19, 2016 at 4:55 PM, Greg Parker via swift-evolution < swift-evolution@swift.org> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution < > swift-evolution@swift.org> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution < > swift-evolution@swift.org> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be
Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with
removing the external parameter name “arrayLiteral”. Not only is it
unnecessary, but it’s confusing too: variadic parameters are not the same
as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible. Set([“a”,
“b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks
existing code that expects #1. You could try to overload the no-name
initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com Runtime Wrangler

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The horse has probably bolted on this one, but in general array literals
can be confusing when used for anything other than an array. A compromise
position might be to remove the array literal `init` from `Set` and replace
it with a var arg `init`. It would break code, but not that much since
`Set` is new and a migration tool could find it easily. This gives:

    let sI = Set(1) // Set of Int
    let sAI = Set([1]) // Set of array of Int

···

On Wednesday, 20 January 2016, Greg Parker <gparker@apple.com> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution < > swift-evolution@swift.org > <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com > <javascript:_e(%7B%7D,'cvml','jackl@apple.com');>> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution < > swift-evolution@swift.org > <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be
Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with
removing the external parameter name “arrayLiteral”. Not only is it
unnecessary, but it’s confusing too: variadic parameters are not the same
as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible. Set([“a”,
“b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks
existing code that expects #1. You could try to overload the no-name
initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com
<javascript:_e(%7B%7D,'cvml','gparker@apple.com');> Runtime Wrangler

--
  -- Howard.

Keep in mind Array<T> cannot currently be stored in a Set (it will bridge to NSArray if the contained elements are compatible, which then supports Hashable.)

The non-labelled initializer expects a formed SequenceType.

If you want to use varargs, you can use Set(arrayLiteral:[1], [2], [3]) - so no removal of the array literal convertible conformance needed, it does what you want already

-DW

···

On Jan 19, 2016, at 6:56 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

The horse has probably bolted on this one, but in general array literals can be confusing when used for anything other than an array. A compromise position might be to remove the array literal `init` from `Set` and replace it with a var arg `init`. It would break code, but not that much since `Set` is new and a migration tool could find it easily. This gives:

    let sI = Set(1) // Set of Int
    let sAI = Set([1]) // Set of array of Int

On Wednesday, 20 January 2016, Greg Parker <gparker@apple.com <mailto:gparker@apple.com>> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org <>> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com <>> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution <swift-evolution@swift.org <>> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with removing the external parameter name “arrayLiteral”. Not only is it unnecessary, but it’s confusing too: variadic parameters are not the same as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible. Set([“a”, “b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks existing code that expects #1. You could try to overload the no-name initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com <> Runtime Wrangler

--
  -- Howard.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

What about the mathematical Set notation?:

let numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}

But this is highly ambiguous in those cases:
let numbers = {} // closure ()->()
let numbers = {3} // closure ()->Int

So a type annotation is still needed at least for empty Sets and single element ones. There could be also some difficulties while parsing the swift file.

As some others have said I'm not sure whether such additional syntax pays off.

- Maximilian

···

Am 19.01.2016 um 23:00 schrieb T.J. Usiyan via swift-evolution <swift-evolution@swift.org>:

I agree that the probably isn't a better story for literals and Sets and that I wish that there were a better story.

The best that I can think of is some sort of flag outside of the Array literal, for instance, #["A", "B", "C"] or just using keys that people aren't already accustomed to like option-'\' and option-shift-'\'. «"A", "B", "C"]»

TJ

On Tue, Jan 19, 2016 at 4:55 PM, Greg Parker via swift-evolution <swift-evolution@swift.org> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution <swift-evolution@swift.org> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with removing the external parameter name “arrayLiteral”. Not only is it unnecessary, but it’s confusing too: variadic parameters are not the same as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible. Set([“a”, “b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks existing code that expects #1. You could try to overload the no-name initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com Runtime Wrangler

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Sure, as I said I think the horse has bolted on this one and as you
correctly point out you can get round the problem. Its just not as neat as
just having a var arg initialiser and no array literal initialiser.

···

On 20 January 2016 at 15:59, David Waite <david@alkaline-solutions.com> wrote:

Keep in mind Array<T> cannot currently be stored in a Set (it will bridge
to NSArray if the contained elements are compatible, which then supports
Hashable.)

The non-labelled initializer expects a formed SequenceType.

If you want to use varargs, you can use Set(arrayLiteral:[1], [2], [3]) -
so no removal of the array literal convertible conformance needed, it does
what you want already

-DW

On Jan 19, 2016, at 6:56 PM, Howard Lovatt via swift-evolution < > swift-evolution@swift.org> wrote:

The horse has probably bolted on this one, but in general array literals
can be confusing when used for anything other than an array. A compromise
position might be to remove the array literal `init` from `Set` and replace
it with a var arg `init`. It would break code, but not that much since
`Set` is new and a migration tool could find it easily. This gives:

    let sI = Set(1) // Set of Int
    let sAI = Set([1]) // Set of array of Int

On Wednesday, 20 January 2016, Greg Parker <gparker@apple.com> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution < >> swift-evolution@swift.org> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution < >> swift-evolution@swift.org> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be
Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with
removing the external parameter name “arrayLiteral”. Not only is it
unnecessary, but it’s confusing too: variadic parameters are not the same
as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible.
Set([“a”, “b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks
existing code that expects #1. You could try to overload the no-name
initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com Runtime Wrangler

--
  -- Howard.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
  -- Howard.

This also works (currently):
    [1, 2] as Set

I think this is unambiguous, works with lots of things and doesn't need
to introduce new Set-specific syntax. The downside is that it's slightly
more verbose. I generally don't use Set literals often, and when I do it's
as a static let; so I don't consider the extra few characters from this
expression to be an issue.

If you can represent it concisely with an existing literal type then I
think it's worthwhile doing that, it keeps the language simple.

Andrew

···

On Wed, Jan 20, 2016 at 9:31 AM, Maximilian Hünenberger < swift-evolution@swift.org> wrote:

What about the mathematical Set notation?:

let numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}

But this is highly ambiguous in those cases:
let numbers = {} // closure ()->()
let numbers = {3} // closure ()->Int

So a type annotation is still needed at least for empty Sets and single
element ones. There could be also some difficulties while parsing the swift
file.

As some others have said I'm not sure whether such additional syntax pays
off.

- Maximilian

Am 19.01.2016 um 23:00 schrieb T.J. Usiyan via swift-evolution < > swift-evolution@swift.org>:

I agree that the probably isn't a better story for literals and Sets and
that I wish that there were a better story.

The best that I can think of is some sort of flag outside of the Array
literal, for instance, #["A", "B", "C"] or just using keys that people
aren't already accustomed to like option-'\' and option-shift-'\'. «"A",
"B", "C"]»

TJ

On Tue, Jan 19, 2016 at 4:55 PM, Greg Parker via swift-evolution < > swift-evolution@swift.org> wrote:

On Jan 18, 2016, at 2:55 PM, Howard Lovatt via swift-evolution < >> swift-evolution@swift.org> wrote:

On Tuesday, 19 January 2016, Jack Lawrence <jackl@apple.com> wrote:

On Jan 18, 2016, at 2:50 PM, Liam Butler-Lawrence via swift-evolution < >> swift-evolution@swift.org> wrote:

Set("a", "b", "c”) doesn’t compile. It currently has to be
Set(arrayLiteral: "a", "b", "c”). That said, I’d be satisfied with
removing the external parameter name “arrayLiteral”. Not only is it
unnecessary, but it’s confusing too: variadic parameters are not the same
as an Array.

init(arrayLiteral:) is there to satisfy ArrayLiteralConvertible.
Set([“a”, “b”, “c”]) works just fine.

Sure, but you could add another overload without the label.

Only if you break existing code. Consider this expression:

    Set(["a", "b"])

Is this
1. a Set<String> with two elements "a" and "b"
2. a Set<Array<String>> with one element ["a", "b"]

Currently it means #1. You could change it to mean #2, but that breaks
existing code that expects #1. You could try to overload the no-name
initializer, but that will be confusing to humans in some cases.

--
Greg Parker gparker@apple.com Runtime Wrangler

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution