Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-28 Thread Haravikk via swift-evolution

> On 28 May 2016, at 20:16, Xiaodi Wu  wrote:
> 
> I couldn't disagree more. Generic programming is a far more advanced concept 
> than arrays and dictionaries, and learners should be able to use them without 
> contending with angle brackets they don't understand.
> 
> Fundamentally, even for an experienced user of the language, working with 
> Collections and Sequences requires more consideration than working with 
> arrays. It's not just a matter of how these things are spelled. It seems like 
> you want to punish users who don't have the time or inclination to genericize 
> their algorithms by making them write more, in the hopes that if you make 
> working with arrays difficult enough, people will switch to generic 
> containers. That's bonkers.

It’s not about making working with arrays difficult, but if we can make working 
with basic generic collections/sequences just as easy, then it makes sense to 
encourage their use as much as possible. Like in the example below, 
Sequence.of is pretty straightforward, and far more flexible and useful 
than just using [Foo], as you can trivially change the type of collection you 
use later.

More complex generics definitely need to be explored separately, but 
Sequence.of should be just as simple to use as [Foo], it’s just a little 
longer because of the ability to distinguish between sequence and collection.

> On Sat, May 28, 2016 at 14:38 Haravikk via swift-evolution 
> > wrote:
> 
>> On 27 May 2016, at 15:31, plx via swift-evolution > > wrote:
>> 
>>   protocol Sequence {
> 
>> typealias of == S: Self where S.Iterator.Element == E
>>   }
>> 
> 
>>   // sequence-accepting variant
>>   func doSomething(values: S) { … }
> 
> 
> This is a nice alternative; would it actually need to be declared in the 
> angle brackets? Could it be done as:
> 
>   func doSomething(values:Sequence.of) { … }
> 
> As long as it would work the same as a generic declaration this could be a 
> good way to do it, either that or a SequenceOf type alias as mentioned.
> 
> 
> Still, I kind of feel like we need to do something with the array type 
> shorthand, but I wonder if perhaps we could just get rid of it altogether, to 
> prevent its use entirely? i.e- all instances of [Foo] can be replaced with 
> Array, but we would encourage the use of 
> Sequence.of/SequenceOf/Collection.of/CollectionOf first wherever possible.
> 
> As more types become available that are ArrayLiteralConvertible it seems like 
> we should discourage restriction of a parameter to Array except when a 
> developer explicitly chooses it. This problem will come up with the 
> Dictionary type shorthand as well if Swift gets some kind of Map protocol to 
> abstract it, and we don’t even have a Set-specific syntax so it seems like it 
> may be fairer to remove these shorthands.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-28 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 28, 2016, at 1:38 PM, Haravikk via swift-evolution 
>  wrote:
> 
> 
>> On 27 May 2016, at 15:31, plx via swift-evolution 
>>  wrote:
>> 
>>   protocol Sequence {
>> typealias of == S: Self where S.Iterator.Element == E
>>   }
>> 
>>   // sequence-accepting variant
>>   func doSomething(values: S) { … }
> 
> This is a nice alternative; would it actually need to be declared in the 
> angle brackets? Could it be done as:
> 
>   func doSomething(values:Sequence.of) { … }
> 
> As long as it would work the same as a generic declaration this could be a 
> good way to do it, either that or a SequenceOf type alias as mentioned.

I think I showed both existential and generic variations didn't I?  You 
certainly could do it either way.  Placing the typealias in the protocol is not 
a bad idea either!

> 
> 
> Still, I kind of feel like we need to do something with the array type 
> shorthand, but I wonder if perhaps we could just get rid of it altogether, to 
> prevent its use entirely? i.e- all instances of [Foo] can be replaced with 
> Array, but we would encourage the use of 
> Sequence.of/SequenceOf/Collection.of/CollectionOf first wherever possible.
> 
> As more types become available that are ArrayLiteralConvertible it seems like 
> we should discourage restriction of a parameter to Array except when a 
> developer explicitly chooses it. This problem will come up with the 
> Dictionary type shorthand as well if Swift gets some kind of Map protocol to 
> abstract it, and we don’t even have a Set-specific syntax so it seems like it 
> may be fairer to remove these shorthands.
> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-28 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 28, 2016, at 12:40 PM, Thorsten Seitz  wrote:
> 
> 
>>> Am 27.05.2016 um 20:47 schrieb Matthew Johnson via swift-evolution 
>>> :
>>> 
>>> 
 On May 27, 2016, at 12:05 PM, Charles Srstka via swift-evolution 
  wrote:
 
 On May 27, 2016, at 9:31 AM, plx via swift-evolution 
  wrote:
 
 For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
 convenience, but for more-complex type associated-type relationships it 
 could start to pay its own way.
>>> 
>>> Is it really that minor, though? For something so commonly encountered as 
>>> methods that take sequences/collections, this:
>>> 
>>> func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])
>>> 
>>> is not only a whole lot easier to type, but is worlds clearer to read than:
>>> 
>>> func doSomething>> S.Generator.Element == Foo, T.Generator.Element == Bar, U.Generator.Element 
>>> == Baz>(foos: S, bars: T, bazzes: U)
>>> 
>>> Not only is the latter line intimidating to look at as is, but it separates 
>>> the contained type from the parameters themselves. Given how unwieldy this 
>>> second form is, it seems almost certain that the former line will be used 
>>> more frequently in the real world.
>> 
>> When generalized existentials are introduced (Austin Zheng has a proposal 
>> for this) you will be able to do this (assuming we switch to the `&` syntax:
>> 
>> typealias SequenceOf = Sequence where .Element == T
>> 
>> func doSomething(foos: SequenceOf, bars: SequenceOf, bazzes: 
>> SequenceOf)
> 
> That’s a really nice solution, which gets even nicer with plx suggestion of 
> putting the typealias within the protocol like this: 
> 
> protocol Sequence {
> typealias of = S: Self where .Element == E
> }

That is very nice!

> 
> -Thorsten
> 
> 
> 
>> 
>> It’s still slightly more verbose than the array shorthand, but it’s a far 
>> cry from what you have to do with generics today.
>> 
>> If you wanted it to be generic you could write it as:
>> 
>> func doSomething, T: SequenceOf, 
>> SequenceOf(foos: S, bars: T, bazzes: U)
>> 
>>> 
>>> Charles
>>> 
>>> ___
>>> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-28 Thread Thorsten Seitz via swift-evolution

> Am 27.05.2016 um 20:47 schrieb Matthew Johnson via swift-evolution 
> :
> 
> 
>> On May 27, 2016, at 12:05 PM, Charles Srstka via swift-evolution 
>> > wrote:
>> 
>>> On May 27, 2016, at 9:31 AM, plx via swift-evolution 
>>> > wrote:
>>> 
>>> For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
>>> convenience, but for more-complex type associated-type relationships it 
>>> could start to pay its own way.
>> 
>> Is it really that minor, though? For something so commonly encountered as 
>> methods that take sequences/collections, this:
>> 
>> func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])
>> 
>> is not only a whole lot easier to type, but is worlds clearer to read than:
>> 
>> func doSomething> S.Generator.Element == Foo, T.Generator.Element == Bar, U.Generator.Element 
>> == Baz>(foos: S, bars: T, bazzes: U)
>> 
>> Not only is the latter line intimidating to look at as is, but it separates 
>> the contained type from the parameters themselves. Given how unwieldy this 
>> second form is, it seems almost certain that the former line will be used 
>> more frequently in the real world.
> 
> When generalized existentials are introduced (Austin Zheng has a proposal for 
> this) you will be able to do this (assuming we switch to the `&` syntax:
> 
> typealias SequenceOf = Sequence where .Element == T
> 
> func doSomething(foos: SequenceOf, bars: SequenceOf, bazzes: 
> SequenceOf)

That’s a really nice solution, which gets even nicer with plx suggestion of 
putting the typealias within the protocol like this: 

protocol Sequence {
typealias of = S: Self where .Element == E
}

-Thorsten



> 
> It’s still slightly more verbose than the array shorthand, but it’s a far cry 
> from what you have to do with generics today.
> 
> If you wanted it to be generic you could write it as:
> 
> func doSomething, T: SequenceOf, 
> SequenceOf(foos: S, bars: T, bazzes: U)
> 
>> 
>> Charles
>> 
>> ___
>> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 27, 2016, at 3:43 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> On May 24, 2016, at 9:35 PM
> 
> on Tue May 24 2016, Matthew Johnson  wrote:
> 
>> , Austin Zheng
>>  wrote:
>> 
>>On Tue, May 24, 2016 at 4:24 PM, Brent Royal-Gordon
>> wrote:
>> 
>>> I’m not sure what you mean about introducing type unsafely.
>> 
>>What I mean is that once you do this:
>> 
>>let x: AnyCollection = myArrayOfCharacters
>>let y: AnyCollection = myString.characters
>> 
>>Both `x` and `y` have indices of type `Any`, and will now
>>accept each others' indices:
>> 
>>for i in x.indices {
>>print(y[i]) // Oops!
>>}
>> 
>>If this rule:
>> 
>>> The generalized existentials proposal goes out of its way to be
>>explicit about the fact that only type safe operations would be 
>> visible
>>through the existential.
>> 
>>Is trying to say that this isn't the case because APIs using the
>>collection's `Index` are not exposed on an `AnyCollection`, well, then
>>I'm not sure what `AnyCollection` is actually supposed to be used for.
>> 
>>If there's any way that the rules that I've proposed can be relaxed 
>> without
>>sacrificing type safety, I would love to hear it. I think the difference 
>> in
>>'power' in this regard between a function that uses generic types and a
>>function that uses existentials is something inherent to how each works,
>>though.
>> 
>> The primary difference is the freedom to accept an index which is invalid and
>> call fatalError when you get it. We don't want existentials to do something
>> that. But with user-defined types we have the flexibility to do that if we
>> decide it is the right design.
> 
> I'm not sure I agree that Existentials shouldn't do that.  The amount of
> boilerplate one needs to construct a user-defined simulation of an
> existential in these cases can be prohibitive.  Why shouldn't the
> compiler handle it for us?

I know it involves a lot of boilerplate that is better avoided and can be 
prohibitive and steer one away from designs that might otherwise be useful.

But the behavior of AnyCollection (specifically AnyIndex) involves custom logic 
that decides where and how to introduce the potential for fatalError.  I 
definitely don't want the compiler doing this without an explicit request of 
some kind.  Existentials should at least be safe by default.  If we *really* 
need a way to introduce unsafe existentials it should be opt-in (I have no idea 
what that might look like).  But I'm not sure it's worth introducing a feature 
like that just to make it easier to create types with an unsafe interface.

But why would you want the unsafe behavior of AnyCollection when we could have 
a safe 'typealias AnyCollection = Collection where .Element == T'?  You 
would be able to safely use indexes received from the collection to index back 
into it.  Usage that would cause a runtime crash can be caught at compile time. 
 The only thing you wouldn't be able to do is take an index received from one 
collection and use with another.  Is there a specific use case the current 
design supports that the safer existential would not?

-Matthew

> 
> -- 
> Dave
> 
> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Dave Abrahams via swift-evolution

On May 24, 2016, at 9:35 PM

on Tue May 24 2016, Matthew Johnson  wrote:

> , Austin Zheng
>  wrote:
>
> On Tue, May 24, 2016 at 4:24 PM, Brent Royal-Gordon
>  wrote:
>
> > I’m not sure what you mean about introducing type unsafely.
>
> What I mean is that once you do this:
>
> let x: AnyCollection = myArrayOfCharacters
> let y: AnyCollection = myString.characters
>
> Both `x` and `y` have indices of type `Any`, and will now
> accept each others' indices:
>
> for i in x.indices {
> print(y[i]) // Oops!
> }
>
> If this rule:
>
> > The generalized existentials proposal goes out of its way to be
> explicit about the fact that only type safe operations would be 
> visible
> through the existential.
>
> Is trying to say that this isn't the case because APIs using the
> collection's `Index` are not exposed on an `AnyCollection`, well, then
> I'm not sure what `AnyCollection` is actually supposed to be used for.
>
> If there's any way that the rules that I've proposed can be relaxed 
> without
> sacrificing type safety, I would love to hear it. I think the difference 
> in
> 'power' in this regard between a function that uses generic types and a
> function that uses existentials is something inherent to how each works,
> though.
>
> The primary difference is the freedom to accept an index which is invalid and
> call fatalError when you get it. We don't want existentials to do something
> that. But with user-defined types we have the flexibility to do that if we
> decide it is the right design.

I'm not sure I agree that Existentials shouldn't do that.  The amount of
boilerplate one needs to construct a user-defined simulation of an
existential in these cases can be prohibitive.  Why shouldn't the
compiler handle it for us?

-- 
Dave

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Charles Srstka via swift-evolution
> On May 27, 2016, at 1:53 PM, Xiaodi Wu  wrote:
> 
> Firstly, the syntax is about to get a lot cleaner. Soon, your example will be:
> 
> func doSomething<
> S: Sequence, T: Sequence, U: Sequence
> >(foos: S, bars: T, bazzes: U)
> where S.Element == Foo, T.Element == Bar, U.Element == Baz

I wonder if it would be possible to introduce angle brackets on protocols to 
enumerate associated-type requirements? AFAIK, currently the angle brackets are 
not allowed at all, so it would be purely additive. Then, you could do 
something like:

func doSomething(foos: Sequence, bars: Sequence, bazzes: Sequence)

I don’t know about you, but that looks so much cleaner, for a function that 
doesn’t itself need to be generic.

(The generalized existentials solution is good, too. However, it requires 
making a separate typealias for every protocol you want to do this with, 
whereas the above idea wouldn’t.)

> Second, this syntax shows necessary complexity. Case in point: an array is a 
> Collection with randomly accessible elements, yet in your example you chose 
> SequenceType (aka Sequence). An instance of a type conforming to Sequence may 
> or may not have randomly accessible elements, it may or may not be consumed 
> after one pass, it may or may not have copy-on-write behavior, and it may or 
> may not be laid out contiguously in memory (which is not guaranteed for all 
> arrays but is for arrays with elements of primitive type)--and that's if it's 
> entirely held in memory at all.
> 
> By writing out the function declaration the way it's shown above, it's clear 
> what considerations that function will have to take into account. Assuming 
> that it can operate on arbitrary sequences just like it can an array is a 
> recipe for a lot of pain.

Yeah, I defaulted to Sequence just because I’ve been writing stuff lately that 
just iterates through a collection that’s passed in. If what the OP is 
proposing came to pass, it would need to map to Collection instead. Of course, 
sometimes all you need is a Sequence, so your point is well-taken. We do need 
*some* way to simplify this syntax, though.

Charles

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Dave Abrahams via swift-evolution

on Fri May 27 2016, Xiaodi Wu  wrote:

> Firstly, the syntax is about to get a lot cleaner. Soon, your example will be:
>
> func doSomething<
> S: Sequence, T: Sequence, U: Sequence
>>(foos: S, bars: T, bazzes: U)
> where S.Element == Foo, T.Element == Bar, U.Element == Baz
>
> Second, this syntax shows necessary complexity. Case in point: an array is a
> Collection with randomly accessible elements, yet in your example you chose
> SequenceType (aka Sequence). An instance of a type conforming to Sequence may 
> or
> may not have randomly accessible elements, it may or may not be consumed after
> one pass, it may or may not have copy-on-write behavior, 

I know it's not really the point you're making, but “has copy-on-write
behavior” is not something we capture in a protocol constraint, and
it probably shouldn't be.

> and it may or may not be laid out contiguously in memory (which is not
> guaranteed for all arrays but is for arrays with elements of primitive
> type)--and that's if it's entirely held in memory at all.
>
> By writing out the function declaration the way it's shown above, it's clear
> what considerations that function will have to take into account. Assuming 
> that
> it can operate on arbitrary sequences just like it can an array is a recipe 
> for
> a lot of pain.
>
> On Fri, May 27, 2016 at 12:05 Charles Srstka via swift-evolution
>  wrote:
>
> On May 27, 2016, at 9:31 AM, plx via swift-evolution
>  wrote:
>
> For the Sequence/Collection it’s a lot of work for IMHO a rather minor
> convenience, but for more-complex type associated-type relationships 
> it
> could start to pay its own way.
>
> Is it really that minor, though? For something so commonly encountered as
> methods that take sequences/collections, this:
>
> func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])
>
> is not only a whole lot easier to type, but is worlds clearer to read 
> than:
>
> func doSomething S.Generator.Element == Foo, T.Generator.Element == Bar, 
> U.Generator.Element
> == Baz>(foos: S, bars: T, bazzes: U)
>
> Not only is the latter line intimidating to look at as is, but it 
> separates
> the contained type from the parameters themselves. Given how unwieldy this
> second form is, it seems almost certain that the former line will be used
> more frequently in the real world.
>
> Charles
>
> ___
> 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

-- 
Dave

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Xiaodi Wu via swift-evolution
Firstly, the syntax is about to get a lot cleaner. Soon, your example will
be:

func doSomething<
S: Sequence, T: Sequence, U: Sequence
>(foos: S, bars: T, bazzes: U)
where S.Element == Foo, T.Element == Bar, U.Element == Baz

Second, this syntax shows necessary complexity. Case in point: an array is
a Collection with randomly accessible elements, yet in your example you
chose SequenceType (aka Sequence). An instance of a type conforming to
Sequence may or may not have randomly accessible elements, it may or may
not be consumed after one pass, it may or may not have copy-on-write
behavior, and it may or may not be laid out contiguously in memory (which
is not guaranteed for all arrays but is for arrays with elements of
primitive type)--and that's if it's entirely held in memory at all.

By writing out the function declaration the way it's shown above, it's
clear what considerations that function will have to take into account.
Assuming that it can operate on arbitrary sequences just like it can an
array is a recipe for a lot of pain.

On Fri, May 27, 2016 at 12:05 Charles Srstka via swift-evolution <
swift-evolution@swift.org> wrote:

> On May 27, 2016, at 9:31 AM, plx via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> For the Sequence/Collection it’s a lot of work for IMHO a rather minor
> convenience, but for more-complex type associated-type relationships it
> could start to pay its own way.
>
>
> Is it really that minor, though? For something so commonly encountered as
> methods that take sequences/collections, this:
>
> func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])
>
> is not only a whole lot easier to type, but is worlds clearer to read than:
>
> func doSomething S.Generator.Element == Foo, T.Generator.Element == Bar, U.Generator.Element
> == Baz>(foos: S, bars: T, bazzes: U)
>
> Not only is the latter line intimidating to look at as is, but it
> separates the contained type from the parameters themselves. Given how
> unwieldy this second form is, it seems almost certain that the former line
> will be used more frequently in the real world.
>
> Charles
>
> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Matthew Johnson via swift-evolution

> On May 27, 2016, at 12:05 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> On May 27, 2016, at 9:31 AM, plx via swift-evolution 
>> > wrote:
>> 
>> For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
>> convenience, but for more-complex type associated-type relationships it 
>> could start to pay its own way.
> 
> Is it really that minor, though? For something so commonly encountered as 
> methods that take sequences/collections, this:
> 
> func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])
> 
> is not only a whole lot easier to type, but is worlds clearer to read than:
> 
> func doSomething S.Generator.Element == Foo, T.Generator.Element == Bar, U.Generator.Element 
> == Baz>(foos: S, bars: T, bazzes: U)
> 
> Not only is the latter line intimidating to look at as is, but it separates 
> the contained type from the parameters themselves. Given how unwieldy this 
> second form is, it seems almost certain that the former line will be used 
> more frequently in the real world.

When generalized existentials are introduced (Austin Zheng has a proposal for 
this) you will be able to do this (assuming we switch to the `&` syntax:

typealias SequenceOf = Sequence where .Element == T

func doSomething(foos: SequenceOf, bars: SequenceOf, bazzes: 
SequenceOf)

It’s still slightly more verbose than the array shorthand, but it’s a far cry 
from what you have to do with generics today.

If you wanted it to be generic you could write it as:

func doSomething, T: SequenceOf, SequenceOf(foos: 
S, bars: T, bazzes: U)

> 
> Charles
> 
> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Charles Srstka via swift-evolution
> On May 27, 2016, at 9:31 AM, plx via swift-evolution 
>  wrote:
> 
> For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
> convenience, but for more-complex type associated-type relationships it could 
> start to pay its own way.

Is it really that minor, though? For something so commonly encountered as 
methods that take sequences/collections, this:

func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])

is not only a whole lot easier to type, but is worlds clearer to read than:

func doSomething(foos: S, bars: T, bazzes: U)

Not only is the latter line intimidating to look at as is, but it separates the 
contained type from the parameters themselves. Given how unwieldy this second 
form is, it seems almost certain that the former line will be used more 
frequently in the real world.

Charles

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread plx via swift-evolution
Late response!

As-specified, although I understand the *motivation* for this suggestion, I 
can’t support the specific proposal whatsoever.

That said, I do think there’d be a lot of value in a way to add “convenience 
type predicates” (terrible name, please improve!) to declarations, so that e.g.:

  protocol Sequence {

// one possibility for a declaration:
typealias of == S: Self where S.Iterator.Element == E

  }

…would allow you to write your examples like this:

  // sequence-accepting variant
  func doSomething(values: S) { … }

  // hopefully, this would work also:
  func doSomething

…either as an extension of the existing generic-typealias syntax or as a 
separate-but-similar feature.

For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
convenience, but for more-complex type associated-type relationships it could 
start to pay its own way.

> On May 24, 2016, at 12:57 PM, Haravikk via swift-evolution 
>  wrote:
> 
> One thing that I see a lot in code, and sometimes have to stop myself from 
> doing, is using shorthand array types, such as [Foo], in function 
> declarations where CollectionType could just as easily be used. For example, 
> the following two declarations can take collections of values, but the first 
> will only take them in the form of an Array:
> 
>   func doSomething(values:[Foo]) { … }
>   func doSomething C.Generator.Element:Foo>(values:C) { … }
> 
> The latter form is something that new users of Swift tend not to know they 
> can do, and which even experienced Swift developers may not use for the sake 
> of brevity, but it can come up quite a lot. What I’d like to propose is that 
> [Foo], when used in a function, should produce the latter form behind the 
> scenes, requiring the developer to specify Array if they actually need 
> it to be an Array for some reason. Though this would become inconsistent with 
> variables/properties which would still have to be Array since a type is 
> required.
> 
> 
> An alternative would be if we could specify protocol generics in a more 
> succinct form, for example:
> 
>   func doSomething(values:Collection) { … }
>   func doSomething(values:Sequence) { … } // Many array functions 
> are linear anyway so could just as easily take sequences
> 
> Note: This would not be the same as type-erased wrappers such as 
> AnySequence, but rather a shorthand for "Sequence where 
> Generator.Element:Foo"
> 
> 
> 
> In essence I’m hoping to discuss whether we should try to remove the 
> temptation to limit functions to arrays only or not, or if there are other 
> ways to encourage more use of sequence and collection for flexibility; I try 
> wherever possible to have my methods take sequences if they can, and only 
> take collections if they need to (and never arrays only), but I can 
> understand why not everyone does this, as it’s not the friendliest thing to 
> add and declaring [Foo] looks so much neater.
> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 24, 2016, at 9:35 PM, Austin Zheng  wrote:
> 
> 
> 
>> On Tue, May 24, 2016 at 4:24 PM, Brent Royal-Gordon  
>> wrote:
>> > I’m not sure what you mean about introducing type unsafely.
>> 
>> What I mean is that once you do this:
>> 
>> let x: AnyCollection = myArrayOfCharacters
>> let y: AnyCollection = myString.characters
>> 
>> Both `x` and `y` have indices of type `Any`, and will now accept 
>> each others' indices:
>> 
>> for i in x.indices {
>> print(y[i]) // Oops!
>> }
>> 
>> If this rule:
>> 
>> > The generalized existentials proposal goes out of its way to be explicit 
>> > about the fact that only type safe operations would be visible through the 
>> > existential.
>> 
>> Is trying to say that this isn't the case because APIs using the 
>> collection's `Index` are not exposed on an `AnyCollection`, well, then I'm 
>> not sure what `AnyCollection` is actually supposed to be used for.
>> 
> 
> If there's any way that the rules that I've proposed can be relaxed without 
> sacrificing type safety, I would love to hear it. I think the difference in 
> 'power' in this regard between a function that uses generic types and a 
> function that uses existentials is something inherent to how each works, 
> though.

The primary difference is the freedom to accept an index which is invalid and 
call fatalError when you get it.  We don't want existentials to do something 
that.  But with user-defined types we have the flexibility to do that if we 
decide it is the right design.

>  
>> --
>> Brent Royal-Gordon
>> Architechies
>> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Austin Zheng via swift-evolution
Sorry. That sentence should read: [Foo] is an array. Collection means
nothing in Swift right now, but it really does look awfully like a generic
protocol by analogy.

Since I'm here, I might as well keep on digging...

Right now, we have good syntax delineation. Generic types and functions are
immediately obvious because of the characteristic angle brackets placed
after the function or type name (with the exception of the three big
sugared generic types in the stdlib - Array, Dictionary, and Optional). We
also have protocol<...> to build an existential out of one or more
protocols, although there has been some discussion in other threads about
whether people might confuse that syntax with generic type syntax and
whether it should be changed as a result. Associated types don't use the
angle brackets, but they aren't really generic types - they can be used to
constrain generic types, but they also show up in places like defining
constrained protocol extensions, whose methods don't necessarily need to be
used in a generic function.

I think the fact that it's reasonably easy to tell these three loosely
defined families of type features apart is a valuable aspect of the
language's design, and loosening this ability should be done very carefully.

Austin



On Tue, May 24, 2016 at 7:19 PM, Austin Zheng  wrote:

> I regret mentioning existentials; I am aware that an existential that
> isn't sufficiently constrained will never be able to provide the same
> guarantees as a generic type variable. My argument is that even a partially
> constrained existential is useful if there is a useful set of APIs that
> don't touch the associated types in question. I do not believe that they
> fulfill the same role as generics, and I apologize for writing a response
> that strongly implied they were.
>
> That being said, my opinion regarding this suggestion is still this: [Foo]
> is not an array, Collection is not a generic protocol, and I am
> strongly against any sort of compiler magic that makes those types mean
> anything other than what they appear to be.
>
> Austin
>
> If this rule:
>>
>> > The generalized existentials proposal goes out of its way to be
>> explicit about the fact that only type safe operations would be visible
>> through the existential.
>>
>> Is trying to say that this isn't the case because APIs using the
>> collection's `Index` are not exposed on an `AnyCollection`, well, then I'm
>> not sure what `AnyCollection` is actually supposed to be used for.
>>
>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Austin Zheng via swift-evolution
I regret mentioning existentials; I am aware that an existential that isn't
sufficiently constrained will never be able to provide the same guarantees
as a generic type variable. My argument is that even a partially
constrained existential is useful if there is a useful set of APIs that
don't touch the associated types in question. I do not believe that they
fulfill the same role as generics, and I apologize for writing a response
that strongly implied they were.

That being said, my opinion regarding this suggestion is still this: [Foo]
is not an array, Collection is not a generic protocol, and I am
strongly against any sort of compiler magic that makes those types mean
anything other than what they appear to be.

Austin

If this rule:
>
> > The generalized existentials proposal goes out of its way to be explicit
> about the fact that only type safe operations would be visible through the
> existential.
>
> Is trying to say that this isn't the case because APIs using the
> collection's `Index` are not exposed on an `AnyCollection`, well, then I'm
> not sure what `AnyCollection` is actually supposed to be used for.
>

> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Matthew Johnson via swift-evolution

> On May 24, 2016, at 6:24 PM, Brent Royal-Gordon  
> wrote:
> 
>> I’m not sure what you mean about introducing type unsafely.
> 
> What I mean is that once you do this:
> 
>   let x: AnyCollection = myArrayOfCharacters
>   let y: AnyCollection = myString.characters
> 
> Both `x` and `y` have indices of type `Any`, and will now accept 
> each others' indices:
> 
>   for i in x.indices {
>   print(y[i]) // Oops!
>   }
> 
> If this rule:
> 
>> The generalized existentials proposal goes out of its way to be explicit 
>> about the fact that only type safe operations would be visible through the 
>> existential.
> 
> Is trying to say that this isn't the case because APIs using the collection's 
> `Index` are not exposed on an `AnyCollection`, well, then I'm not sure what 
> `AnyCollection` is actually supposed to be used for.

Yeah, this is actually a good point.  We will probably have to implement the 
type-erased wrappers manually if we want this behavior.  I don’t know for sure 
but I imagine maybe it is considered acceptable in this case because you can 
already hit a fatal error with a bad array index anyway, so it isn’t totally 
unexpected.

> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Charles Srstka via swift-evolution
> On May 24, 2016, at 5:45 PM, Haravikk via swift-evolution 
>  wrote:
> 
>> On 24 May 2016, at 21:14, Leonardo Pessoa > > wrote:
>> 
>> My first question here would be "what's the gain?" I understand
>> CollectionTypes and arrays may be something different but I myself
>> admit I don't know and wonder how that change would be a benefit to
>> us?
> 
> Instead of functions only accepting an Array, which is a specific type, they 
> would accept any collection type, including all the lazy collections.

Among other things, one practical advantage of this is that since ArraySlice 
conforms to CollectionType, one could simply subscript an array if they wanted 
to send only a subset of its contents to a method, without having to incur the 
performance cost of creating a new array.

Charles

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Brent Royal-Gordon via swift-evolution
> I’m not sure what you mean about introducing type unsafely.

What I mean is that once you do this:

let x: AnyCollection = myArrayOfCharacters
let y: AnyCollection = myString.characters

Both `x` and `y` have indices of type `Any`, and will now accept 
each others' indices:

for i in x.indices {
print(y[i]) // Oops!
}

If this rule:

> The generalized existentials proposal goes out of its way to be explicit 
> about the fact that only type safe operations would be visible through the 
> existential.

Is trying to say that this isn't the case because APIs using the collection's 
`Index` are not exposed on an `AnyCollection`, well, then I'm not sure what 
`AnyCollection` is actually supposed to be used for.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Matthew Johnson via swift-evolution

> On May 24, 2016, at 5:45 PM, Haravikk via swift-evolution 
>  wrote:
> 
> 
>> On 24 May 2016, at 21:14, Leonardo Pessoa > > wrote:
>> 
>> My first question here would be "what's the gain?" I understand
>> CollectionTypes and arrays may be something different but I myself
>> admit I don't know and wonder how that change would be a benefit to
>> us?
> 
> Instead of functions only accepting an Array, which is a specific type, they 
> would accept any collection type, including all the lazy collections.
> 
>> On 24 May 2016, at 21:16, T.J. Usiyan > > wrote:
>> 
>> I agree that Sequence or Collection is what is more often 'meant' but what 
>> you propose is an awkward to explain/defend betrayal, in my opinion.
> 
> I’m not sure I’d call it a “betrayal”, there aren’t many methods on Array 
> that aren’t covered by CollectionType, and those that are aren’t available as 
> an immutable type anyway (which all function parameters are now), so to do 
> anything array-specific requires extra steps that a fix-it might be able to 
> cover if CollectionType is too general for your method.
> 
> The problem is that when there’s a shorthand, people tend to use it, but the 
> problem is that most of the time any collection or sequence type will do, and 
> that an array isn’t actually required at all. After seeing a bunch of 
> examples of [Foo] before I knew about how to handle generics properly I found 
> it a tricky habit to break. Could be more of a failing in the way Swift is 
> being taught right now perhaps, but then generics can’t really be taught any 
> sooner either, it’s tricky.
> 
> It may be too much of a breaking change I’ll grant, but at the same time it 
> seems better to shake this up and get people using the correct method for 
> passing/receiving collections by default.

The idea of shorthand for commonly used generics and / or existentials is 
interesting.  I’m not sure stealing the array syntax which is both familiar and 
similar to other languages is the right approach but it is worth considering. 

If we do go down this path I think an important part of the discussion is 
whether the shorthand introduces an implicit generic parameter, whether it uses 
an existential, or whether the user has control over this.  Joe Groff has 
mentioned that he would like these to have the same behavior eventually, but 
that is not the case today.  I’m not sure what is involved in making the 
behavior the same or what the timeframe for that might look like.

> 
>> On 24 May 2016, at 21:15, Austin Zheng > > wrote:
>> 
>> Better support for existentials (see the generics manifesto, 
>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md 
>> ) 
>> should obviate the need for any sort of sugar or compiler magic to do this 
>> kind of thing.
>> 
>> typealias AnyCollection = Any
>> func doSomething(collection: AnyCollection)
> 
> Hmm, that does look like it could cover it, thanks for linking this! Just to 
> double check, but Any is a new root for all types then, so this isn’t the 
> same as a type-erased wrapper?

Yes, generalized existentials are roughly equivalent to type-erased wrappers 
except you don’t have to write them manually.

> ___
> 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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Brent Royal-Gordon via swift-evolution
> Better support for existentials (see the generics manifesto, 
> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md) should 
> obviate the need for any sort of sugar or compiler magic to do this kind of 
> thing.
> 
> typealias AnyCollection = Any
> func doSomething(collection: AnyCollection)

That isn't really the same thing, though. Any is an existential; it 
introduces indirection which would not be present in the generic version and, 
in this case, it erases several associated types, potentially introducing 
type-unsafety as well.

-- 
Brent Royal-Gordon
Architechies

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