Re: [swift-evolution] @NSCopying currently does not affect initializers

2017-01-31 Thread Torin Kwok via swift-evolution
I have given out a proposal about it: Compensate for the inconsistency of 
@NSCopying's behavior. Please give it some reviews. Thanks.

Best,
Torin




On Tue, Jan 31, 2017 at 2:34 PM +0800, "Torin Kwok via swift-evolution" 
 wrote:










Thanks Doug, I’m writing a proposal about it.

- Torin

> On 31 Jan 2017, at 07:20, Douglas Gregor  wrote:
> 
> 
>> On Jan 28, 2017, at 10:43 PM, Rod Brown via swift-evolution  wrote:
>> 
>> I agree that there is an issue here.
>> 
>> While I understand that the initialiser avoids the full setter for direct 
>> access, I would expect the attribute to mean that the substituted direct 
>> access still applied the attribute you marked the API with. I would consider 
>> the fact that it doesn't work as a dangerous gap in the API.
>> 
>> It is also concerning if we consider how this will work with Property 
>> Behaviours that are planned for Swift in the future. If we made NSCopying a 
>> property behaviour, the direct access would mean it too would not be invoked 
>> at initial access so I'm not sure how the best way to get around this is - 
>> should we do compiler magic to copy in the initialiser, or should we warn if 
>> we don't detect a call to copy() or copy(with:) in the initialiser?
> 
> I think we should be doing the compiler magic to call copy(with:) in the 
> initializer, because that seems like the most direct way to maintain the 
> @NSCopying contract without changing the underlying direct-storage model.
> 
>> I think we at least need to do something here. It's a very convoluted piece 
>> of logic to say the @NSCopying attribute doesn't work in an initialiser and 
>> it's hardly intuitive despite the fair reasoning.
> 
> I agree that we need to do something here. It feels like it’s just a bug—that 
> this is the only way that @NSCopying makes sense in an attribute. Might even 
> be a good starter bug for someone who wants to dip their tows into the type 
> checker!
> 
>   - Doug
> 
>> 
>> Rod
>> 
>>> On 29 Jan 2017, at 4:47 pm, Torin Kwok via swift-evolution  wrote:
>>> 
>>> Yep, I also admit the design of forbidding calling a setter before full
>>> class initialization is reasonable and what's really annoying is the
>>> inconsistency.
>>> 
>>> However, making @NSCopying attribute not subjects to the fact that
>>> setters would not be invoked in initializers perhaps is viable too. In
>>> the other words, assigning a value to a property whether or not by
>>> calling a setter has no influence on whether @NSCopying semantic'd work:
>>> copying should always take place after a property has been declared as
>>> @NSCopying.
>>> 
>>> Jean-Daniel writes:
>>> 
> Le 28 janv. 2017 à 05:34, Torin Kwok via swift-evolution  a écrit :
> 
> Hello guys,
> 
> Note: This issue has been originally presented inswift-usersmailling list 
> . And then I post it again here at the suggestion  of Jordan Rose:
> 
> It might be reasonable to change this behavior, but it probably deserves 
> a bit of discussion on swift-evolution; it's not 100%, for-sure a bug.
> --- the original content follows this line ---
> 
> I encountered a strange behavior when I declared a property with the 
> @NSCopying attribute:
> 
> // `Person` class inherits from `NSObject` class and conforms to 
> `NSCopying` protocol
> @NSCopying var employee: Person
> and then assigned an external instance of Person class protocol to this 
> property within the designated init methods:
> 
> // Designated initializer of `Department` class
> init( employee externalEmployee: Person ) {
> self.employee = externalEmployee
> super.init()
> 
> // Assertion would fail since Swift do not actually copy the value 
> assigned to this property 
> // even though `self.employee` has been marked as `@NSCoyping`
> // assert( self.employee !== externalEmployee )
> }
> If I indeed require the deep copying behavior during the init process, 
> instead of taking advantage of @NSCopying attribute, I would have to 
> invoke the copy() method manually:
> 
> init( employee externalEmployee: Person ) {
> // ...
> self.employee = externalEmployee.copy() as! Person  
> // ...
> }
> In fact, what really makes me confusing is that @NSCopying semantic does 
> work properly within the other parts of the class definition such as 
> normal instance methods, or external scope. For instance, if we're 
> assigning an external instance of Person to the self.employee proper of 
> Department directly through setter rather than initializer:
> 
> department.employee = johnAppleseed
> then self.employee property and johnAppleseed variable will no longer 
> share the same underlying object now. In the other words, @NSCopying 
> attribute makes sense.
> 
> After I looked through a great deal of results given by Google, and 

Re: [swift-evolution] The lack of namespaces is leading people astray

2017-01-31 Thread Rien via swift-evolution
I have been known to mimic namespaces as well, however now that SPM is here, I 
no longer see a need for it.

Still, I won’t object to it.

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl





> On 01 Feb 2017, at 06:30, David Sweeris via swift-evolution 
>  wrote:
> 
> 
>> On Jan 30, 2017, at 5:55 AM, Tuur Anton via swift-evolution 
>>  wrote:
>> 
>> The lack of namespaces is making people create all kinds of "design 
>> patterns".
>> 
>> struct API {
>> static let endpoint = "http://example.com/api;
>> }
>> 
>> Here is an "improvement" to the above "design pattern" to prevent 
>> instantiating API:
>> 
>> struct API {
>> private init() {}
>> static let endpoint = "http://example.com/api;
>> }
>> 
>> Finally, here is another "improvement" that uses enum instead of struct to 
>> avoid having to write the private initializer:
>> 
>> enum API {
>> static let endpoint = "http://example.com/api;
>> }
>> 
>> I doubt any of you find this beautiful. Yet these "design patterns" (just 
>> hacks IMO) are spreading like the plague because of the lack of namespaces.
>> 
>> What do you think?
> 
> Personally, I’m in favor of namespaces, but it’s more of a “seems like a good 
> idea” thing than “I need this because ”, at least from my PoV. I’m 
> inclined to just defer to the core team’s judgement on this one.
> 
> On the plus side though, if we ever do get formal namespaces, it should be 
> relatively simple to search for enums with no cases and give a fixit.
> 
> - Dave Sweeris
> 
> ___
> 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] Default Generic Arguments

2017-01-31 Thread Srđan Rašić via swift-evolution
Hah, did I really do that :( I completely missed the fact that `let foo:
Optional = 42` is supported at the moment. I've been programming in Swift
in day zero, but never really used such syntax.

I'll update the PR, thanks for your feedback.

ons. 1. feb. 2017 kl. 00.05 skrev Xiaodi Wu :

> I have concerns about these revisions. It seems you've entirely rejected
> all the options that Alexis has laid out very clearly, and instead you've
> come up with your own rules which are backwards-incompatible with Swift 3.
>
> For instance, the rule "No type inference will happen in type
> declarations" is source-breaking, because type inference currently happens
> in type declarations. You would break every instance of `let foo: Optional
> = 42`.
>
> I would urge you to incorporate Alexis's very clear analysis and then
> adopt one of the options he laid out, i.e., either "prefer user" or "do
> what I mean." Alternatively, if you like none of his options, I believe
> that requiring `<>` to be appended for entirely default arguments would
> avoid the issue altogether. Or, if you don't even want to require that, you
> can push the whole problem down the road by specifying that, for now, the
> first generic type cannot have a default. We can then relax the rules later.
>
>
> On Tue, Jan 31, 2017 at 3:15 PM, Srđan Rašić 
> wrote:
>
> I updated the proposal with the things we discussed so far. Have to do
> some more polishing, but feel free to throw your critique of what I have so
> far.
>
> On Sat, Jan 28, 2017 at 1:32 AM, Xiaodi Wu  wrote:
>
> Oh, it's precisely my confidence that a good error message can be devised
> which makes me ponder whether "prefer user" is the ideal rule. Having a
> stricter rule isn't necessarily bad if the error message makes it easy to
> remedy.
>
> In your example, "prefer user" would object at the line where you make
> your Something. I think that makes for a much cleaner error. By contrast,
> DWIM necessitates the acrobatics you show above, where the compiler will
> have to keep track of a defaulted type for each variable as long as it's in
> scope and propose remote fix-its at the declaration site based on how it's
> later used. Now what happens if there's an action() that takes only
> Something arguments and an action2() that takes only Something
> arguments? Will you have an alternating cycle of fix-its that don't fix the
> problem?
>
>
> On Fri, Jan 27, 2017 at 18:07 Karl Wagner  wrote:
>
>
> On 27 Jan 2017, at 01:30, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Cool, thanks--that makes sense.
>
> Personally, although DWIM is appealing, I think if we are to go all-out on
> your stance that "adding a default to an existing type parameter should be
> a strict source-breaking change," then "prefer user" is the one rule that
> maximally clarifies the scenario. With that rule, in the evolution
> scenarios that I brought up, either the user-specified default and the
> inferred literal type line up perfectly or it is guaranteed to be
> source-breaking. IMO, that consistency would bring more clarity than DWIM,
> which might prompt a user to be confused why sometimes the compiler "gets
> it" and other times it doesn’t.
>
>
> I’m not sure, I think it will be easy enough for users to figure out where
> the problem is because it will create a type-mismatch.
> When type mismatches occur, the only place to look is the variable
> definition, because that is where the type is defined.
>
> This is such a narrow case that I’m sure we can provide good diagnostics
> for it. The pattern could be:
>
> - A generic parameter mismatch (i.e. trying to use a value of type
> MyType where type MyType is expected), and
> - X and Y are both {Whatever}LiteralConvertible, and
> - X is the default type bound to that parameter, and
> - the value was initialised using a {Whatever} literal, where an instance
> of the parameter was expected
>
> In that case, we could introduce a simple fix-it: replacing one of the
> literal values with "(literal as Y)”
>
> for example:
>
> struct 

Re: [swift-evolution] [Discussion] mailing list alternative

2017-01-31 Thread Thorsten Seitz via swift-evolution
While I'm not really happy with the mailing list, this is mostly due to 
restrictions of iOS Mail which makes keeping track of relevant threads and 
filtering out threads I'm not interested in difficult.

The mailing list has one important advantage over a web interface: most of my 
reading happens on a train to and from work. On this train the connection is 
for most parts of the ride so bad that I can't download new messages, but 
fortunately that is not necessary because I can read all those messages I 
downloaded earlier on the railway station.
With a web interface I expect that to be much more problematic because it would 
have to download each message or maybe at least each thread on demand.

So for me keeping the mailing list while using a modern forum in parallel would 
be the ideal solution!

-Thorsten 

> Am 26.01.2017 um 07:13 schrieb Ted kremenek via swift-evolution 
> :
> 
> I had this same question in my mind — especially if one can reply to an email 
> and it posts back to the forum.
> 
> The mailing list model works well for those who want to get the entire feed 
> of traffic, and easily monitor which threads they want to follow/read using 
> the standard affordances in their mail program (e.g., mail filters, flagging 
> messages, and so on).
> 
> The forum interface provides a way for people to just jump in and participate 
> on specific topics, provide better (standard) rendering of content — such as 
> code (which can be nice for technical conversations), and better archiving 
> and possibly be more searchable.
> 
> If Discourse supports participation via email, it seems we get the best of 
> both worlds, as you say.  I'm not super familiar with what Discourse can do 
> in this regards.
> 
>> On Jan 25, 2017, at 9:22 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>  wrote:
>> 
>> Can a forum be configured to send each new post to the mailing list with 
>> proper subject line?
>> 
>> If so, that would enable a best-of-both-worlds scenario—or at least the 
>> ability to dip our toes in a forum to see if it works, while still showing 
>> everything on-list.
>> 
>> Nevin
>> 
>> 
>> 
>>> On Wed, Jan 25, 2017 at 11:28 PM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
 On Jan 25, 2017, at 6:57 PM, Xiaodi Wu  wrote:
 
>> Signing up for mailing lists is straightforward, yes—but that’s only a 
>> small part of it. Signing up for a mailing list is a *commitment.* Once 
>> you do it, your inbox will be inundated with mailing list posts, making 
>> it difficult to find messages that actually have been intended for you 
>> personally. Therefore, you’ll have to deal with that somehow. You can 
>> set up rules in Mail to route mailing list posts to a separate folder, 
>> but that won’t help you if you access your webmail from a public 
>> machine. 
> 
> FWIW, I subscribe to many mailing lists in gmail and have it auto filter 
> emails to mailing lists into a separate mailbox (well, really, tags) for 
> each list.  It works great for me.
> 
> This doesn’t detract from your point about it being a commitment though.
 
 It does kind of imply a follow-up question, though: is it _undesirable_ 
 that signing up for a mailing list is a modicum of commitment?
>>> 
>>> I’m mixed on that.  On the one hand, it is great to have some level of 
>>> commitment before people inject their opinion into the mix for some 
>>> discussion.  OTOH, I’m sympathetic to the desire that a lot of people want 
>>> to just “follow along” without participating, and the mailman web interface 
>>> is pretty uninspired.
>>> 
>>> -Chris
>>> 
>>> 
>>> ___
>>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] The lack of namespaces is leading people astray

2017-01-31 Thread David Sweeris via swift-evolution

> On Jan 30, 2017, at 5:55 AM, Tuur Anton via swift-evolution 
>  wrote:
> 
> The lack of namespaces is making people create all kinds of "design patterns".
> 
> struct API {
> static let endpoint = "http://example.com/api "
> }
> 
> Here is an "improvement" to the above "design pattern" to prevent 
> instantiating API:
> 
> struct API {
> private init() {}
> static let endpoint = "http://example.com/api "
> }
> 
> Finally, here is another "improvement" that uses enum instead of struct to 
> avoid having to write the private initializer:
> 
> enum API {
> static let endpoint = "http://example.com/api "
> }
> 
> I doubt any of you find this beautiful. Yet these "design patterns" (just 
> hacks IMO) are spreading like the plague because of the lack of namespaces.
> 
> What do you think?

Personally, I’m in favor of namespaces, but it’s more of a “seems like a good 
idea” thing than “I need this because ”, at least from my PoV. I’m 
inclined to just defer to the core team’s judgement on this one.

On the plus side though, if we ever do get formal namespaces, it should be 
relatively simple to search for enums with no cases and give a fixit.

- Dave Sweeris

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


Re: [swift-evolution] The lack of namespaces is leading people astray

2017-01-31 Thread Step Christopher via swift-evolution
I remain a fan of adding 'namespace' to the language. 

In the meantime I'll continue using the enum static member approach. But I 
would love to have something semantically cleaner. 

> El ene. 30, 2017, a las 3:09 PM, Robert Widmann via swift-evolution 
>  escribió:
> 
> I submitted a proposal with TJ a while ago that tried to address this 
> comprehensively because the trouble is if you just want submodules you have 
> to define how our current penta-scheme of access control interacts with each 
> level or do away with a few of them to make some simplifying assumptions.  It 
> also raises an ambiguity with qualified imports that has to be worked out.
> 
>> On Jan 30, 2017, at 9:00 AM, Adrian Zubarev via swift-evolution 
>>  wrote:
>> 
>> If I remember correctly it has been said that we don't need namespaces in 
>> favor of submodules, which schould solve these issues.
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> Am 30. Januar 2017 um 14:55:31, Tuur Anton via swift-evolution 
>> (swift-evolution@swift.org) schrieb:
>> 
>>> The lack of namespaces is making people create all kinds of "design 
>>> patterns".
>>> 
>>> struct API {
>>> static let endpoint = "http://example.com/api;
>>> }
>>> 
>>> Here is an "improvement" to the above "design pattern" to prevent 
>>> instantiating API:
>>> 
>>> struct API {
>>> private init() {}
>>> static let endpoint = "http://example.com/api;
>>> }
>>> 
>>> Finally, here is another "improvement" that uses enum instead of struct to 
>>> avoid having to write the private initializer:
>>> 
>>> enum API {
>>> static let endpoint = "http://example.com/api;
>>> }
>>> 
>>> I doubt any of you find this beautiful. Yet these "design patterns" (just 
>>> hacks IMO) are spreading like the plague because of the lack of namespaces.
>>> 
>>> What do you think?
>>> 
>>> ___
>>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 10:15 PM, Dave Abrahams  wrote:

>
> on Tue Jan 31 2017, Xiaodi Wu  wrote:
>
> > On Tue, Jan 31, 2017 at 2:53 PM, Max Moiseev  wrote:
> >
> >> Hi Brent,
> >>
> >> Thanks a lot for your suggestions! After having discussed them with
> Dave,
> >> we came up with the following design that I personally like a lot.
> >>
> >> enum Overflowing { case .withOverflow }
>
> I really dislike “Overflowing”; it seems to imply that there *will* be
> overflow.  How about
>
>   enum ReportingOverflow { case .reportingOverflow }


Much better. Since the kind of reporting we're getting is the overflow
flag, maybe even `FlaggingOverflow`?


>
> >>
> >> enum FullWidth { case .fullWidth }
> >>
> >> protocol FixedWidthInteger {
> >>   func adding(_ other: Self, _: Overflowing) -> (partialValue: Self,
> >> overflow: ArithmeticOverflow)
> >>   func subtracting(_ other: Self, _: Overflowing) -> (partialValue:
> Self,
> >> overflow: ArithmeticOverflow)
> >>   func multiplied(by other: Self, _: Overflowing) -> (partialValue:
> Self,
> >> overflow: ArithmeticOverflow)
> >>   func divided(by other: Self, _: Overflowing) -> (partialValue: Self,
> >> overflow: ArithmeticOverflow)
> >>
> >>   func multiplied(by other: Self, _: FullWidth) -> DoubleWidth
> >>   func dividing(_ other: DoubleWidth, _: FullWidth) -> (quotient:
> >> Self, remainder: Self)
> >> }
> >>
> >>
> >> Call sites would look like:
> >>
> >> x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)
> >>
> >> a little different for the division:
> >>
> >> x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)
> >>
> >> Note the inverse-ness of `dividing`, but the lack of the argument label
> >> makes it quite natural.
> >>
> >
> > This is an improvement in many ways, I think. However `.fullWidth` vs.
> > `DoubleWidth` seems less than ideal.
>
> IMO .fullWidth is an improvement over .DoubleWidth, at least for
> multiplication.  The latter just repeats type information, where the
> former tells you something about *how* the operation is to be performed.


Sure, I buy that.

> I get that you can't reuse `DoubleWidth` for the single-case enum, but
> > still.
> >
> > Now that * and &* no longer used the `multiplied(by:)` spelling, is
> there a
> > reason not to take advantage of overloading on the return value for these
> > very specialized methods?
> >
> > ```
> > protocol FixedWidthInteger {
> >   typealias OverflowFlagging = (partialValue: Self, overflow:
> > ArithmeticOverflow)
> >   func multiplied(by other: Self) -> OverflowFlagging
> >   func multiplied(by other: Self) -> DoubleWidth
> > }
> > ```
> >
> > You'd then write `x.multiplied(by: y) as OverflowFlagging` and
> > `x.multiplied(by: y) as DoubleWidth`
>
> It's too subtle, IMO, and any place that type context is available to
> disambiguate the result, it
>
>  x.multiplied(by: y)
>
> will look like it should be rewritten as
>
>  x * y
>

Fair point.


> > With respect to `dividing` vs `divided`, IMO it'd be a tricky name,
> > especially for non-English speakers. The "ed/ing" rule has these suffixes
> > used pretty interchangeably to indicate a non-mutating operation,
> depending
> > on the vagaries of the English language, but we've never had an "ed" and
> an
> > "ing" used for completely different things on the same type, as far as
> I'm
> > aware. Why not move the `dividing` version to DoubleWidth, where it can
> be
> > a proper `divided(by:)`?
>
> Max and I discussed this; I'll let him answer.


Awesome. Everything else is really stylistic, but I really think the
linguistic quirk of `dividing` vs `divided` is suboptimal from a
helping-people-write-correct-code standpoint.


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


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Dave Abrahams via swift-evolution

on Tue Jan 31 2017, Xiaodi Wu  wrote:

> On Tue, Jan 31, 2017 at 2:53 PM, Max Moiseev  wrote:
>
>> Hi Brent,
>>
>> Thanks a lot for your suggestions! After having discussed them with Dave,
>> we came up with the following design that I personally like a lot.
>>
>> enum Overflowing { case .withOverflow }

I really dislike “Overflowing”; it seems to imply that there *will* be
overflow.  How about

  enum ReportingOverflow { case .reportingOverflow }

>> 
>> enum FullWidth { case .fullWidth }
>>
>> protocol FixedWidthInteger {
>>   func adding(_ other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>>   func subtracting(_ other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>>   func multiplied(by other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>>   func divided(by other: Self, _: Overflowing) -> (partialValue: Self,
>> overflow: ArithmeticOverflow)
>>
>>   func multiplied(by other: Self, _: FullWidth) -> DoubleWidth
>>   func dividing(_ other: DoubleWidth, _: FullWidth) -> (quotient:
>> Self, remainder: Self)
>> }
>>
>>
>> Call sites would look like:
>>
>> x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)
>>
>> a little different for the division:
>>
>> x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)
>>
>> Note the inverse-ness of `dividing`, but the lack of the argument label
>> makes it quite natural.
>>
>
> This is an improvement in many ways, I think. However `.fullWidth` vs.
> `DoubleWidth` seems less than ideal. 

IMO .fullWidth is an improvement over .DoubleWidth, at least for
multiplication.  The latter just repeats type information, where the
former tells you something about *how* the operation is to be performed.

> I get that you can't reuse `DoubleWidth` for the single-case enum, but
> still.
>
> Now that * and &* no longer used the `multiplied(by:)` spelling, is there a
> reason not to take advantage of overloading on the return value for these
> very specialized methods?
>
> ```
> protocol FixedWidthInteger {
>   typealias OverflowFlagging = (partialValue: Self, overflow:
> ArithmeticOverflow)
>   func multiplied(by other: Self) -> OverflowFlagging
>   func multiplied(by other: Self) -> DoubleWidth
> }
> ```
>
> You'd then write `x.multiplied(by: y) as OverflowFlagging` and
> `x.multiplied(by: y) as DoubleWidth`

It's too subtle, IMO, and any place that type context is available to
disambiguate the result, it 

 x.multiplied(by: y)

will look like it should be rewritten as

 x * y

> With respect to `dividing` vs `divided`, IMO it'd be a tricky name,
> especially for non-English speakers. The "ed/ing" rule has these suffixes
> used pretty interchangeably to indicate a non-mutating operation, depending
> on the vagaries of the English language, but we've never had an "ed" and an
> "ing" used for completely different things on the same type, as far as I'm
> aware. Why not move the `dividing` version to DoubleWidth, where it can be
> a proper `divided(by:)`?

Max and I discussed this; I'll let him answer.


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


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Dave Abrahams via swift-evolution

on Tue Jan 31 2017, Xiaodi Wu  wrote:

> But that's not getting to the biggest hitch with your proposal. If
> subscript were lenient, then `arr[lenient: 42...]` would also have to give
> you a result even if `arr.count == 21`.
>
> This is not at all what Dave Abrahams was proposing, though (unless I
> totally misunderstand). He truly doesn't want an infinite range. He wants
> to use a terser notation for saying: I want x to be the lower bound of a
> range for which I don't yet know (or haven't bothered to find out) the
> finite upper bound. It would be plainly clear, if spelled as `arr[from:
> 42]`, that if `arr.count < 43` then this expression will trap, but if
> `arr.count >= 43` then this expression will give you the rest of the
> elements.

I think you do misunderstand.  Notionally, 0... is an infinite range.
The basic programming model for numbers in swift is (to a first
approximation), program as if there's no overflow, and we'll catch you
by trapping if your assumption is wrong.  It doesn't make sense for the
semantics of 0... to depend on the deduced type of 0 or the
representable range of Int

for example, 

for x in zip(n..., someArray) {

}

How many iterations should this give you?  If it doesn't process all of
someArray, I want a trap.

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


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jan 31, 2017, at 7:28 PM, Xiaodi Wu  wrote:
> 
>> On Tue, Jan 31, 2017 at 7:08 PM, Matthew Johnson  
>> wrote:
>> 
>>> On Jan 31, 2017, at 6:54 PM, Xiaodi Wu  wrote:
>>> 
 On Tue, Jan 31, 2017 at 6:40 PM, Matthew Johnson  
 wrote:
 
> On Jan 31, 2017, at 6:15 PM, Xiaodi Wu  wrote:
> 
>> On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson 
>>  wrote:
>> 
>>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
 On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris  
 wrote:
 
> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
> 
>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>>  wrote:
>> 
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>>>  wrote:
>>> 
>>> I think that is perfectly reasonable, but then it seems weird to be 
>>> able to iterate over it (with no upper bound) independently of a 
>>> collection). It would surprise me if
>>> ```
>>> for x in arr[arr.startIndex…] { print(x) }
>>> ```
>>> yielded different results than
>>> ```
>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>> ```
>>> which it does under this model.
>> 
>> (I think this how it works... semantically, anyway) Since the upper 
>> bound isn't specified, it's inferred from the context.
>> 
>> In the first case, the context is as an index into an array, so the 
>> upper bound is inferred to be the last valid index.
>> 
>> In the second case, there is no context, so it goes to Int.max. 
>> Then, after the "wrong" context has been established, you try to 
>> index an array with numbers from the too-large range.
>> 
>> Semantically speaking, they're pretty different operations. Why is 
>> it surprising that they have different results?
> 
> I must say, I was originally rather fond of `0...` as a spelling, but 
> IMO, Jaden and others have pointed out a real semantic issue.
> 
> A range is, to put it simply, the "stuff" between two end points. A 
> "range with no upper bound" _has to be_ one that continues forever. 
> The upper bound _must_ be infinity.
 
 Depends… Swift doesn’t allow partial initializations, and neither the 
 `.endIndex` nor the `.upperBound` properties of a `Range` are 
 optional. From a strictly syntactic PoV, a "Range without an 
 upperBound” can’t exist without getting into undefined behavior 
 territory.
 
 Plus, mathematically speaking, an infinite range would be written "[x, 
 ∞)", with an open upper bracket. If you write “[x, ∞]”, with a closed 
 upper bracket, that’s kind of a meaningless statement. I would argue 
 that if we’re going to represent that “infinite” range, the closest 
 Swift spelling would be “x..<“. That leaves the mathematically 
 undefined notation of “[x, ∞]”, spelled as "x…” in Swift, free to let 
 us have “x…” or “…x” (which by similar reasoning can’t mean "(∞, x]”) 
 return one of these:
 enum IncompleteRange {
 case upperValue(T)
 case lowerValue(T)
 }
 which we could then pass to the subscript function of a collection to 
 create the actual Range like this:
 extension Collection {
 subscript(_ ir: IncompleteRange) -> SubSequence {
 switch ir {
 case .lowerValue(let lower): return self[lower ..< 
 self.endIndex]
 case .upperValue(let upper): return self[self.startIndex ..< 
 upper]
 }
 }
 }
>>> 
>>> I understand that you can do this from a technical perspective. But I'm 
>>> arguing it's devoid of semantics.  That is, it's a spelling to dress up 
>>> a number.
>> 
>> It’s not any more devoid of semantics than a partially applied function.
> 
> Yes, but this here is not a partially applied type.
> 
> Nor does it square with your proposal that you should be able to use `for 
> i in 0...` to mean something different from `array[0...]`. We don't have 
> partially applied functions doubling as function calls with default 
> arguments.
 
 I’m not trying to say it’s *exactly* like a partially applied function.
>>> 
>>> I'm not saying you're arguing that point. I'm saying that there is a 
>>> semantic distinction between (1) a range 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 6:54 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 31, 2017 at 6:40 PM, Matthew Johnson  > wrote:
> 
>> On Jan 31, 2017, at 6:15 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson > > wrote:
>> 
>>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris >> > wrote:
>>> 
 On Jan 31, 2017, at 2:04 PM, Xiaodi Wu > wrote:
 
 On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
 > wrote:
 
 On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
 > wrote:
 
> I think that is perfectly reasonable, but then it seems weird to be able 
> to iterate over it (with no upper bound) independently of a collection). 
> It would surprise me if
> ```
> for x in arr[arr.startIndex…] { print(x) }
> ```
> yielded different results than
> ```
> for i in arr.startIndex… { print(arr[i]) } // CRASH
> ```
> which it does under this model.
 
 (I think this how it works... semantically, anyway) Since the upper bound 
 isn't specified, it's inferred from the context.
 
 In the first case, the context is as an index into an array, so the upper 
 bound is inferred to be the last valid index.
 
 In the second case, there is no context, so it goes to Int.max. Then, 
 after the "wrong" context has been established, you try to index an array 
 with numbers from the too-large range.
 
 Semantically speaking, they're pretty different operations. Why is it 
 surprising that they have different results?
 
 I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
 Jaden and others have pointed out a real semantic issue.
 
 A range is, to put it simply, the "stuff" between two end points. A "range 
 with no upper bound" _has to be_ one that continues forever. The upper 
 bound _must_ be infinity.
>>> 
>>> Depends… Swift doesn’t allow partial initializations, and neither the 
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. 
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>>> without getting into undefined behavior territory.
>>> 
>>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>>> bracket, that’s kind of a meaningless statement. I would argue that if 
>>> we’re going to represent that “infinite” range, the closest Swift spelling 
>>> would be “x..<“. That leaves the mathematically undefined notation of “[x, 
>>> ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by 
>>> similar reasoning can’t mean "(∞, x]”) return one of these:
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>> which we could then pass to the subscript function of a collection to 
>>> create the actual Range like this:
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>>> case .upperValue(let upper): return self[self.startIndex ..< upper]
>>> }
>>> }
>>> }
>>> 
>>> I understand that you can do this from a technical perspective. But I'm 
>>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>>> number.
>> 
>> It’s not any more devoid of semantics than a partially applied function.
>> 
>> Yes, but this here is not a partially applied type.
>> 
>> Nor does it square with your proposal that you should be able to use `for i 
>> in 0...` to mean something different from `array[0...]`. We don't have 
>> partially applied functions doubling as function calls with default 
>> arguments.
> 
> I’m not trying to say it’s *exactly* like a partially applied function.
> 
> I'm not saying you're arguing that point. I'm saying that there is a semantic 
> distinction between (1) a range with two bounds where you've only specified 
> the one, and (2) a range with one bound. There must be an answer to the 
> question: what is the nature of the upper bound of `0...`? Either it exists 
> but is not yet known, or it is known that it does not exist (or, it is not 
> yet known whether or not it exists). But these are not the same thing!
> 
>> It is a number or index with added semantics that it provides a lower (or 
>> upper) 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 6:15 PM, Jaden Geller  wrote:
> 
> 
>> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris >> > wrote:
>>> 
 On Jan 31, 2017, at 2:04 PM, Xiaodi Wu > wrote:
 
 On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
 > wrote:
 
 On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
 > wrote:
 
> I think that is perfectly reasonable, but then it seems weird to be able 
> to iterate over it (with no upper bound) independently of a collection). 
> It would surprise me if
> ```
> for x in arr[arr.startIndex…] { print(x) }
> ```
> yielded different results than
> ```
> for i in arr.startIndex… { print(arr[i]) } // CRASH
> ```
> which it does under this model.
 
 (I think this how it works... semantically, anyway) Since the upper bound 
 isn't specified, it's inferred from the context.
 
 In the first case, the context is as an index into an array, so the upper 
 bound is inferred to be the last valid index.
 
 In the second case, there is no context, so it goes to Int.max. Then, 
 after the "wrong" context has been established, you try to index an array 
 with numbers from the too-large range.
 
 Semantically speaking, they're pretty different operations. Why is it 
 surprising that they have different results?
 
 I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
 Jaden and others have pointed out a real semantic issue.
 
 A range is, to put it simply, the "stuff" between two end points. A "range 
 with no upper bound" _has to be_ one that continues forever. The upper 
 bound _must_ be infinity.
>>> 
>>> Depends… Swift doesn’t allow partial initializations, and neither the 
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. 
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>>> without getting into undefined behavior territory.
>>> 
>>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>>> bracket, that’s kind of a meaningless statement. I would argue that if 
>>> we’re going to represent that “infinite” range, the closest Swift spelling 
>>> would be “x..<“. That leaves the mathematically undefined notation of “[x, 
>>> ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by 
>>> similar reasoning can’t mean "(∞, x]”) return one of these:
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>> which we could then pass to the subscript function of a collection to 
>>> create the actual Range like this:
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>>> case .upperValue(let upper): return self[self.startIndex ..< upper]
>>> }
>>> }
>>> }
>>> 
>>> I understand that you can do this from a technical perspective. But I'm 
>>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>>> number.
>> 
>> It’s not any more devoid of semantics than a partially applied function.  It 
>> is a number or index with added semantics that it provides a lower (or 
>> upper) bound on the possible value specified by its type.
> 
> If we treat it as such, we shouldn’t allow users to iterate over it directly:
> ```
> for x in 0… { // <- doesn’t make sense; only partially specified
>   print(“hi”)
> }
> ```
> 
> We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`, 
> providing an overload that constructs each. It would never be ambiguous 
> because `InfiniteRange ` would be the only `Sequence` and `IncompleteRange` 
> would be the only one of these two that is accepted as a collections 
> subscript.
> 
> This *isn’t* that crazy either. There’s precedent for this too. The `..<` 
> operator used to create both ranges and intervals (though it seems those type 
> have started to merge).
> 
> ¯\_(ツ)_/¯

This is what I was getting at, but hadn’t thought the details all the way 
through to realize that we really would need two distinct types here.  I 
apologize for being a little bit sloppy in both my reasoning and my 
terminology.  Thanks for clearing up the details!  :)

> 
>> 
>>> 
>>> 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 6:40 PM, Matthew Johnson 
wrote:

>
> On Jan 31, 2017, at 6:15 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson 
> wrote:
>
>>
>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris 
>> wrote:
>>
>>>
>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
>>>
>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>

 On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
 swift-evolution@swift.org> wrote:

 I think that is perfectly reasonable, but then it seems weird to be
 able to iterate over it (with no upper bound) independently of a
 collection). It would surprise me if
 ```
 for x in arr[arr.startIndex…] { print(x) }
 ```
 yielded different results than
 ```
 for i in arr.startIndex… { print(arr[i]) } // CRASH
 ```
 which it does under this model.


 (I *think* this how it works... semantically, anyway) Since the upper
 bound isn't specified, it's inferred from the context.

 In the first case, the context is as an index into an array, so the
 upper bound is inferred to be the last valid index.

 In the second case, there is no context, so it goes to Int.max. Then,
 *after* the "wrong" context has been established, you try to index an
 array with numbers from the too-large range.

 Semantically speaking, they're pretty different operations. Why is it
 surprising that they have different results?

>>>
>>> I must say, I was originally rather fond of `0...` as a spelling, but
>>> IMO, Jaden and others have pointed out a real semantic issue.
>>>
>>> A range is, to put it simply, the "stuff" between two end points. A
>>> "range with no upper bound" _has to be_ one that continues forever. The
>>> upper bound _must_ be infinity.
>>>
>>>
>>> Depends… Swift doesn’t allow partial initializations, and neither the
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
>>> without getting into undefined behavior territory.
>>>
>>> Plus, mathematically speaking, an infinite range would be written "[x,
>>> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed*
>>> upper bracket, that’s kind of a meaningless statement. I would argue that
>>> if we’re going to represent that “infinite” range, the closest Swift
>>> spelling would be “x..<“. That leaves the mathematically undefined notation
>>> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x”
>>> (which by similar reasoning can’t mean "(∞, x]”) return one of these:
>>>
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>>
>>> which we could then pass to the subscript function of a collection to
>>> create the actual Range like this:
>>>
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex
>>> ]
>>> case .upperValue(let upper): return self[self.startIndex ..<
>>> upper]
>>> }
>>> }
>>> }
>>>
>>>
>> I understand that you can do this from a technical perspective. But I'm
>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a
>> number.
>>
>>
>> It’s not any more devoid of semantics than a partially applied function.
>>
>
> Yes, but this here is not a partially applied type.
>
> Nor does it square with your proposal that you should be able to use `for
> i in 0...` to mean something different from `array[0...]`. We don't have
> partially applied functions doubling as function calls with default
> arguments.
>
>
> I’m not trying to say it’s *exactly* like a partially applied function.
>

I'm not saying you're arguing that point. I'm saying that there is a
semantic distinction between (1) a range with two bounds where you've only
specified the one, and (2) a range with one bound. There must be an answer
to the question: what is the nature of the upper bound of `0...`? Either it
exists but is not yet known, or it is known that it does not exist (or, it
is not yet known whether or not it exists). But these are not the same
thing!

It is a number or index with added semantics that it provides a lower (or
>> upper) bound on the possible value specified by its type.
>>
>>
>> What is such an `IncompleteRange` other than a value of type T? It's
>> not an upper bound or lower bound of anything until it's used to index a
>> collection. Why have a new type (IncompleteRange), a new set of
>> operators (prefix and postfix range operators), and these muddied semantics
>> for something that can be written 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 6:15 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson  > wrote:
> 
>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris > > wrote:
>> 
>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>>> > wrote:
>>> 
 I think that is perfectly reasonable, but then it seems weird to be able 
 to iterate over it (with no upper bound) independently of a collection). 
 It would surprise me if
 ```
 for x in arr[arr.startIndex…] { print(x) }
 ```
 yielded different results than
 ```
 for i in arr.startIndex… { print(arr[i]) } // CRASH
 ```
 which it does under this model.
>>> 
>>> (I think this how it works... semantically, anyway) Since the upper bound 
>>> isn't specified, it's inferred from the context.
>>> 
>>> In the first case, the context is as an index into an array, so the upper 
>>> bound is inferred to be the last valid index.
>>> 
>>> In the second case, there is no context, so it goes to Int.max. Then, after 
>>> the "wrong" context has been established, you try to index an array with 
>>> numbers from the too-large range.
>>> 
>>> Semantically speaking, they're pretty different operations. Why is it 
>>> surprising that they have different results?
>>> 
>>> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
>>> Jaden and others have pointed out a real semantic issue.
>>> 
>>> A range is, to put it simply, the "stuff" between two end points. A "range 
>>> with no upper bound" _has to be_ one that continues forever. The upper 
>>> bound _must_ be infinity.
>> 
>> Depends… Swift doesn’t allow partial initializations, and neither the 
>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. From 
>> a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>> without getting into undefined behavior territory.
>> 
>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>> bracket, that’s kind of a meaningless statement. I would argue that if we’re 
>> going to represent that “infinite” range, the closest Swift spelling would 
>> be “x..<“. That leaves the mathematically undefined notation of “[x, ∞]”, 
>> spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by similar 
>> reasoning can’t mean "(∞, x]”) return one of these:
>> enum IncompleteRange {
>> case upperValue(T)
>> case lowerValue(T)
>> }
>> which we could then pass to the subscript function of a collection to create 
>> the actual Range like this:
>> extension Collection {
>> subscript(_ ir: IncompleteRange) -> SubSequence {
>> switch ir {
>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>> case .upperValue(let upper): return self[self.startIndex ..< upper]
>> }
>> }
>> }
>> 
>> I understand that you can do this from a technical perspective. But I'm 
>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>> number.
> 
> It’s not any more devoid of semantics than a partially applied function.
> 
> Yes, but this here is not a partially applied type.
> 
> Nor does it square with your proposal that you should be able to use `for i 
> in 0...` to mean something different from `array[0...]`. We don't have 
> partially applied functions doubling as function calls with default arguments.

I’m not trying to say it’s *exactly* like a partially applied function.

>  
> It is a number or index with added semantics that it provides a lower (or 
> upper) bound on the possible value specified by its type.
> 
>> 
>> What is such an `IncompleteRange` other than a value of type T? It's not 
>> an upper bound or lower bound of anything until it's used to index a 
>> collection. Why have a new type (IncompleteRange), a new set of operators 
>> (prefix and postfix range operators), and these muddied semantics for 
>> something that can be written `subscript(upTo upperBound: Index) -> 
>> SubSequence { ... }`? _That_ has unmistakable semantics and requires no new 
>> syntax.
> 
> Arguing that it adds too much complexity relative to the value it provides is 
> reasonable.  The value in this use case is mostly syntactic sugar so it’s 
> relatively easy to make the case that it doesn’t cary its weight here.
> 
> The value in Ben’s use case is 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 6:27 PM, Jaden Geller 
wrote:

>
> On Jan 31, 2017, at 4:20 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 31, 2017 at 6:15 PM, Jaden Geller 
> wrote:
>
>>
>> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris 
>> wrote:
>>
>>>
>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
>>>
>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>

 On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
 swift-evolution@swift.org> wrote:

 I think that is perfectly reasonable, but then it seems weird to be
 able to iterate over it (with no upper bound) independently of a
 collection). It would surprise me if
 ```
 for x in arr[arr.startIndex…] { print(x) }
 ```
 yielded different results than
 ```
 for i in arr.startIndex… { print(arr[i]) } // CRASH
 ```
 which it does under this model.


 (I *think* this how it works... semantically, anyway) Since the upper
 bound isn't specified, it's inferred from the context.

 In the first case, the context is as an index into an array, so the
 upper bound is inferred to be the last valid index.

 In the second case, there is no context, so it goes to Int.max. Then,
 *after* the "wrong" context has been established, you try to index an
 array with numbers from the too-large range.

 Semantically speaking, they're pretty different operations. Why is it
 surprising that they have different results?

>>>
>>> I must say, I was originally rather fond of `0...` as a spelling, but
>>> IMO, Jaden and others have pointed out a real semantic issue.
>>>
>>> A range is, to put it simply, the "stuff" between two end points. A
>>> "range with no upper bound" _has to be_ one that continues forever. The
>>> upper bound _must_ be infinity.
>>>
>>>
>>> Depends… Swift doesn’t allow partial initializations, and neither the
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
>>> without getting into undefined behavior territory.
>>>
>>> Plus, mathematically speaking, an infinite range would be written "[x,
>>> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed* 
>>> upper
>>> bracket, that’s kind of a meaningless statement. I would argue that if
>>> we’re going to represent that “infinite” range, the closest Swift spelling
>>> would be “x..<“. That leaves the mathematically undefined notation of “[x,
>>> ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by
>>> similar reasoning can’t mean "(∞, x]”) return one of these:
>>>
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>>
>>> which we could then pass to the subscript function of a collection to
>>> create the actual Range like this:
>>>
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex
>>> ]
>>> case .upperValue(let upper): returnself[self.startIndex ..<
>>> upper]
>>> }
>>> }
>>> }
>>>
>>>
>> I understand that you can do this from a technical perspective. But I'm
>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a
>> number.
>>
>>
>> It’s not any more devoid of semantics than a partially applied function.
>> It is a number or index with added semantics that it provides a lower (or
>> upper) bound on the possible value specified by its type.
>>
>>
>> If we treat it as such, we shouldn’t allow users to iterate over it
>> directly:
>> ```
>> for x in 0… { // <- doesn’t make sense; only partially specified
>>   print(“hi”)
>> }
>> ```
>>
>> We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`,
>> providing an overload that constructs each. It would never be ambiguous
>> because `InfiniteRange ` would be the only `Sequence` and `IncompleteRange`
>> would be the only one of these two that is accepted as a collections
>> subscript.
>>
>> This *isn’t* that crazy either. There’s precedent for this too. The `..<`
>> operator used to create both ranges and intervals (though it seems those
>> type have started to merge).
>>
>> ¯\_(ツ)_/¯
>>
>
>
> Mercifully, those types have completely merged AFAIK. IMO, the long-term
> aim should be to have ... and ..< produce only one kind of range.
>
>
> There are still 2 variants (`Range` and `CountableRange`), but I imagine
> conditional conformances will combine those entirely.
>

Per Dave, that's the goal :)

(I hope conditional 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 5:58 PM, Matthew Johnson 
wrote:

>
> On Jan 31, 2017, at 5:20 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 31, 2017 at 5:04 PM, Matthew Johnson 
> wrote:
>
>>
>> I think it’s fair to say that we get to decide on the semantics of
>> postfix `…`.  “a range with no upper bound” is very reasonable, but
>> wouldn’t another reasonable semantics be “all the rest”, meaning that there
>> *is* an upper bound (the greatest possible value).
>>
>
> "All the rest" is by itself insufficient so far as semantics: all the rest
> _of what_? Supposing that our supplied lower bound is an integer, it must
> be all the rest of the integers. It cannot be all the rest of whatever,
> where whatever might be a collection that you try to subset with `0...`.
> (Recall that collections move indices, but indices know nothing about the
> collections.) It would be exceeding fuzzy for postfix `...` to mean "all
> the rest of whatever I want it to mean"--that, almost tautologically, has
> no semantics at all.
>
>
> Under the latter semantics, a `for i in 0…` loop would terminate after
>> reaching Int.max.  This is probably not what the user intended and would
>> still crash when used in David’s example, but it’s worth considering.
>>
>
> OK, I'm borderline fine with `0... == 0...Int.max`. It at least provides
> some semantics (i.e., we're saying `...` refers to all the rest of the
> values representable by the type used for the lower bound) [**]. But
> Jaden's point still stands, since it would only be consistent if `for i in
> arr[0...]` then traps after `arr.count` just like `for i in
> arr[0...Int.max]` would do. Otherwise, we really are fudging the semantics.
>
>
> If we really want to be honest about the information a value produced
> using postfix `…` carries, it is a partial range with only the lower bound
> specified.  This allows us to assign meaning to that partial range using
> additional context:
>
> * When it is possible to increment Bound directly could be interpreted as
> an (near?) infinite sequence that either terminates or traps when it
> reaches an unrepresentable value.
> * When Bound is an index and the partial range is used as a subscript
> argument it can be interpreted to mean “to the end of the collection”.
>

These are two very different semantics. One says, `i...` is a range with no
upper bound; the other says, `i...` is a lower bound of something. The
objection is twofold. In the first place, those shouldn't be spelled the
same way. In the second place, the "lower bound of something" is already
adequately accommodated by using, well, the actual lower bound. Well, also,
the "range with no upper bound" isn't very useful in practice, especially
if the only compelling use case is one for replacing an existing API that,
well, there is no consensus yet to replace.

This still leaves us with an out of bounds crash in David’s example that
> iterates over a partial range.  This is an artifact of `Array` using Int as
> it’s `Index` rather than an opaque type that does not allow users to
> increment it directly rather than using a collection.
>
> Is the problem in David’s example really that different than the ability
> to directly index an array with any `Int` we want?  It’s not the kind of
> thing that developers would do frequently.  The first time they try it they
> will get a crash and will learn not to do it again.
>
> I’m not necessarily arguing one way or the other.  I’m simply pointing out
> that “partial range” is a perfectly reasonable semantics to consider.
>
>
> [**] It is not perfectly consistent semantically because, as was discussed
> in threads about our numeric protocols, our integer types are supposed to
> model all integers, not just the ones that happen to be representable. Our
> model is imperfect because not all integers fit into finite memory, but
> that's a modeling artifact and not intentional semantics. IIUC, it would be
> otherwise difficult to give a good accounting of, say, the semantics of
> addition if arithmetic overflow were an intentional part of the semantics
> and not an artifact.
>
>
> I haven’t followed all of the details of the numeric protocol
> discussions.  With this in mind, I agree with your proposed semantics of
> trapping after `Int.max` as it sounds more consistent with this intent.
>
>
> I’m not sure if you read Ben’s post regarding `enumerated` or not, but he
>> gave the example of `zip(0…, sequence)` as a more general replacement for
>> `enumerated`.  IMO, he makes a pretty strong case for this.
>>
>>
>>
>> - Dave Sweeris
>>>
>>> ___
>>> 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] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 6:15 PM, Jaden Geller 
wrote:

>
> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris 
> wrote:
>
>>
>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
>>
>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>>
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> I think that is perfectly reasonable, but then it seems weird to be able
>>> to iterate over it (with no upper bound) independently of a collection). It
>>> would surprise me if
>>> ```
>>> for x in arr[arr.startIndex…] { print(x) }
>>> ```
>>> yielded different results than
>>> ```
>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>> ```
>>> which it does under this model.
>>>
>>>
>>> (I *think* this how it works... semantically, anyway) Since the upper
>>> bound isn't specified, it's inferred from the context.
>>>
>>> In the first case, the context is as an index into an array, so the
>>> upper bound is inferred to be the last valid index.
>>>
>>> In the second case, there is no context, so it goes to Int.max. Then,
>>> *after* the "wrong" context has been established, you try to index an
>>> array with numbers from the too-large range.
>>>
>>> Semantically speaking, they're pretty different operations. Why is it
>>> surprising that they have different results?
>>>
>>
>> I must say, I was originally rather fond of `0...` as a spelling, but
>> IMO, Jaden and others have pointed out a real semantic issue.
>>
>> A range is, to put it simply, the "stuff" between two end points. A
>> "range with no upper bound" _has to be_ one that continues forever. The
>> upper bound _must_ be infinity.
>>
>>
>> Depends… Swift doesn’t allow partial initializations, and neither the
>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
>> without getting into undefined behavior territory.
>>
>> Plus, mathematically speaking, an infinite range would be written "[x,
>> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed*
>> upper bracket, that’s kind of a meaningless statement. I would argue that
>> if we’re going to represent that “infinite” range, the closest Swift
>> spelling would be “x..<“. That leaves the mathematically undefined notation
>> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x”
>> (which by similar reasoning can’t mean "(∞, x]”) return one of these:
>>
>> enum IncompleteRange {
>> case upperValue(T)
>> case lowerValue(T)
>> }
>>
>> which we could then pass to the subscript function of a collection to
>> create the actual Range like this:
>>
>> extension Collection {
>> subscript(_ ir: IncompleteRange) -> SubSequence {
>> switch ir {
>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>> case .upperValue(let upper): return self[self.startIndex ..<
>> upper]
>> }
>> }
>> }
>>
>>
> I understand that you can do this from a technical perspective. But I'm
> arguing it's devoid of semantics.  That is, it's a spelling to dress up a
> number.
>
>
> It’s not any more devoid of semantics than a partially applied function.
> It is a number or index with added semantics that it provides a lower (or
> upper) bound on the possible value specified by its type.
>
>
> If we treat it as such, we shouldn’t allow users to iterate over it
> directly:
> ```
> for x in 0… { // <- doesn’t make sense; only partially specified
>   print(“hi”)
> }
> ```
>
> We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`,
> providing an overload that constructs each. It would never be ambiguous
> because `InfiniteRange ` would be the only `Sequence` and `IncompleteRange`
> would be the only one of these two that is accepted as a collections
> subscript.
>
> This *isn’t* that crazy either. There’s precedent for this too. The `..<`
> operator used to create both ranges and intervals (though it seems those
> type have started to merge).
>
> ¯\_(ツ)_/¯
>


Mercifully, those types have completely merged AFAIK. IMO, the long-term
aim should be to have ... and ..< produce only one kind of range.

What is such an `IncompleteRange` other than a value of type T? It's not
> an upper bound or lower bound of anything until it's used to index a
> collection. Why have a new type (IncompleteRange), a new set of
> operators (prefix and postfix range operators), and these muddied semantics
> for something that can be written `subscript(upTo upperBound: Index) ->
> SubSequence { ... }`? _That_ has unmistakable semantics and requires no new
> syntax.
>
>
> Arguing that it adds 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:20 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 31, 2017 at 6:15 PM, Jaden Geller  > wrote:
> 
>> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris >> > wrote:
>>> 
 On Jan 31, 2017, at 2:04 PM, Xiaodi Wu > wrote:
 
 On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
 > wrote:
 
 On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
 > wrote:
 
> I think that is perfectly reasonable, but then it seems weird to be able 
> to iterate over it (with no upper bound) independently of a collection). 
> It would surprise me if
> ```
> for x in arr[arr.startIndex…] { print(x) }
> ```
> yielded different results than
> ```
> for i in arr.startIndex… { print(arr[i]) } // CRASH
> ```
> which it does under this model.
 
 (I think this how it works... semantically, anyway) Since the upper bound 
 isn't specified, it's inferred from the context.
 
 In the first case, the context is as an index into an array, so the upper 
 bound is inferred to be the last valid index.
 
 In the second case, there is no context, so it goes to Int.max. Then, 
 after the "wrong" context has been established, you try to index an array 
 with numbers from the too-large range.
 
 Semantically speaking, they're pretty different operations. Why is it 
 surprising that they have different results?
 
 I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
 Jaden and others have pointed out a real semantic issue.
 
 A range is, to put it simply, the "stuff" between two end points. A "range 
 with no upper bound" _has to be_ one that continues forever. The upper 
 bound _must_ be infinity.
>>> 
>>> Depends… Swift doesn’t allow partial initializations, and neither the 
>>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. 
>>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>>> without getting into undefined behavior territory.
>>> 
>>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>>> bracket, that’s kind of a meaningless statement. I would argue that if 
>>> we’re going to represent that “infinite” range, the closest Swift spelling 
>>> would be “x..<“. That leaves the mathematically undefined notation of “[x, 
>>> ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by 
>>> similar reasoning can’t mean "(∞, x]”) return one of these:
>>> enum IncompleteRange {
>>> case upperValue(T)
>>> case lowerValue(T)
>>> }
>>> which we could then pass to the subscript function of a collection to 
>>> create the actual Range like this:
>>> extension Collection {
>>> subscript(_ ir: IncompleteRange) -> SubSequence {
>>> switch ir {
>>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>>> case .upperValue(let upper): returnself[self.startIndex ..< upper]
>>> }
>>> }
>>> }
>>> 
>>> I understand that you can do this from a technical perspective. But I'm 
>>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>>> number.
>> 
>> It’s not any more devoid of semantics than a partially applied function.  It 
>> is a number or index with added semantics that it provides a lower (or 
>> upper) bound on the possible value specified by its type.
> 
> If we treat it as such, we shouldn’t allow users to iterate over it directly:
> ```
> for x in 0… { // <- doesn’t make sense; only partially specified
>   print(“hi”)
> }
> ```
> 
> We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`, 
> providing an overload that constructs each. It would never be ambiguous 
> because `InfiniteRange ` would be the only `Sequence` and `IncompleteRange` 
> would be the only one of these two that is accepted as a collections 
> subscript.
> 
> This *isn’t* that crazy either. There’s precedent for this too. The `..<` 
> operator used to create both ranges and intervals (though it seems those type 
> have started to merge).
> 
> ¯\_(ツ)_/¯
> 
> 
> Mercifully, those types have completely merged AFAIK. IMO, the long-term aim 
> should be to have ... and ..< produce only one kind of range.

There are still 2 variants 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:15 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> We don't have partially applied functions doubling as function calls with 
> default arguments.

I think this best summarizes my problem with simultaneously treating `0…` as a 
partially specified range (waiting for another “argument” from the collection) 
and as an infinite range (defaulting that argument to Int.max).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 4:09 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris > > wrote:
>> 
>>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>>> > wrote:
>>> 
 I think that is perfectly reasonable, but then it seems weird to be able 
 to iterate over it (with no upper bound) independently of a collection). 
 It would surprise me if
 ```
 for x in arr[arr.startIndex…] { print(x) }
 ```
 yielded different results than
 ```
 for i in arr.startIndex… { print(arr[i]) } // CRASH
 ```
 which it does under this model.
>>> 
>>> (I think this how it works... semantically, anyway) Since the upper bound 
>>> isn't specified, it's inferred from the context.
>>> 
>>> In the first case, the context is as an index into an array, so the upper 
>>> bound is inferred to be the last valid index.
>>> 
>>> In the second case, there is no context, so it goes to Int.max. Then, after 
>>> the "wrong" context has been established, you try to index an array with 
>>> numbers from the too-large range.
>>> 
>>> Semantically speaking, they're pretty different operations. Why is it 
>>> surprising that they have different results?
>>> 
>>> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
>>> Jaden and others have pointed out a real semantic issue.
>>> 
>>> A range is, to put it simply, the "stuff" between two end points. A "range 
>>> with no upper bound" _has to be_ one that continues forever. The upper 
>>> bound _must_ be infinity.
>> 
>> Depends… Swift doesn’t allow partial initializations, and neither the 
>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. From 
>> a strictly syntactic PoV, a "Range without an upperBound” can’t exist 
>> without getting into undefined behavior territory.
>> 
>> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
>> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
>> bracket, that’s kind of a meaningless statement. I would argue that if we’re 
>> going to represent that “infinite” range, the closest Swift spelling would 
>> be “x..<“. That leaves the mathematically undefined notation of “[x, ∞]”, 
>> spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by similar 
>> reasoning can’t mean "(∞, x]”) return one of these:
>> enum IncompleteRange {
>> case upperValue(T)
>> case lowerValue(T)
>> }
>> which we could then pass to the subscript function of a collection to create 
>> the actual Range like this:
>> extension Collection {
>> subscript(_ ir: IncompleteRange) -> SubSequence {
>> switch ir {
>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>> case .upperValue(let upper): return self[self.startIndex ..< upper]
>> }
>> }
>> }
>> 
>> I understand that you can do this from a technical perspective. But I'm 
>> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
>> number.
> 
> It’s not any more devoid of semantics than a partially applied function.  It 
> is a number or index with added semantics that it provides a lower (or upper) 
> bound on the possible value specified by its type.

If we treat it as such, we shouldn’t allow users to iterate over it directly:
```
for x in 0… { // <- doesn’t make sense; only partially specified
  print(“hi”)
}
```

We __could__ introduce 2 types, `IncompleteRange` and `InfiniteRange`, 
providing an overload that constructs each. It would never be ambiguous because 
`InfiniteRange ` would be the only `Sequence` and `IncompleteRange` would be 
the only one of these two that is accepted as a collections subscript.

This *isn’t* that crazy either. There’s precedent for this too. The `..<` 
operator used to create both ranges and intervals (though it seems those type 
have started to merge).

¯\_(ツ)_/¯

> 
>> 
>> What is such an `IncompleteRange` other than a value of type T? It's not 
>> an upper bound or lower bound of anything until it's used to index a 
>> collection. Why have a new type (IncompleteRange), a new set of operators 
>> (prefix and postfix range operators), and these muddied semantics for 
>> something that can be written `subscript(upTo upperBound: Index) -> 
>> SubSequence { ... }`? _That_ has unmistakable semantics and requires no new 
>> syntax.
> 
> Arguing that it adds too much complexity relative to 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 6:09 PM, Matthew Johnson 
wrote:

>
> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris 
> wrote:
>
>>
>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
>>
>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>>
>>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> I think that is perfectly reasonable, but then it seems weird to be able
>>> to iterate over it (with no upper bound) independently of a collection). It
>>> would surprise me if
>>> ```
>>> for x in arr[arr.startIndex…] { print(x) }
>>> ```
>>> yielded different results than
>>> ```
>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>> ```
>>> which it does under this model.
>>>
>>>
>>> (I *think* this how it works... semantically, anyway) Since the upper
>>> bound isn't specified, it's inferred from the context.
>>>
>>> In the first case, the context is as an index into an array, so the
>>> upper bound is inferred to be the last valid index.
>>>
>>> In the second case, there is no context, so it goes to Int.max. Then,
>>> *after* the "wrong" context has been established, you try to index an
>>> array with numbers from the too-large range.
>>>
>>> Semantically speaking, they're pretty different operations. Why is it
>>> surprising that they have different results?
>>>
>>
>> I must say, I was originally rather fond of `0...` as a spelling, but
>> IMO, Jaden and others have pointed out a real semantic issue.
>>
>> A range is, to put it simply, the "stuff" between two end points. A
>> "range with no upper bound" _has to be_ one that continues forever. The
>> upper bound _must_ be infinity.
>>
>>
>> Depends… Swift doesn’t allow partial initializations, and neither the
>> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
>> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
>> without getting into undefined behavior territory.
>>
>> Plus, mathematically speaking, an infinite range would be written "[x,
>> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed*
>> upper bracket, that’s kind of a meaningless statement. I would argue that
>> if we’re going to represent that “infinite” range, the closest Swift
>> spelling would be “x..<“. That leaves the mathematically undefined notation
>> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x”
>> (which by similar reasoning can’t mean "(∞, x]”) return one of these:
>>
>> enum IncompleteRange {
>> case upperValue(T)
>> case lowerValue(T)
>> }
>>
>> which we could then pass to the subscript function of a collection to
>> create the actual Range like this:
>>
>> extension Collection {
>> subscript(_ ir: IncompleteRange) -> SubSequence {
>> switch ir {
>> case .lowerValue(let lower): return self[lower ..< self.endIndex]
>> case .upperValue(let upper): return self[self.startIndex ..<
>> upper]
>> }
>> }
>> }
>>
>>
> I understand that you can do this from a technical perspective. But I'm
> arguing it's devoid of semantics.  That is, it's a spelling to dress up a
> number.
>
>
> It’s not any more devoid of semantics than a partially applied function.
>

Yes, but this here is not a partially applied type.

Nor does it square with your proposal that you should be able to use `for i
in 0...` to mean something different from `array[0...]`. We don't have
partially applied functions doubling as function calls with default
arguments.


> It is a number or index with added semantics that it provides a lower (or
> upper) bound on the possible value specified by its type.
>
>
> What is such an `IncompleteRange` other than a value of type T? It's
> not an upper bound or lower bound of anything until it's used to index a
> collection. Why have a new type (IncompleteRange), a new set of
> operators (prefix and postfix range operators), and these muddied semantics
> for something that can be written `subscript(upTo upperBound: Index) ->
> SubSequence { ... }`? _That_ has unmistakable semantics and requires no new
> syntax.
>
>
> Arguing that it adds too much complexity relative to the value it provides
> is reasonable.  The value in this use case is mostly syntactic sugar so
> it’s relatively easy to make the case that it doesn’t cary its weight here.
>
> The value in Ben’s use case is a more composable alternative to
> `enumerated`.  I find this to be a reasonably compelling example of the
> kind of thing a partial range might enable.
>

Ben's use case is not a "partial range." It's a bona fide range with no
upper bound.


> I also tend to find concise notation important for clarity as long as it
> isn’t obscure or idiosyncratic.  With that in mind, I think I lean in favor
> of `…` so long 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 5:35 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris  > wrote:
> 
>> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
>> > wrote:
>> 
>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>> > wrote:
>> 
>>> I think that is perfectly reasonable, but then it seems weird to be able to 
>>> iterate over it (with no upper bound) independently of a collection). It 
>>> would surprise me if
>>> ```
>>> for x in arr[arr.startIndex…] { print(x) }
>>> ```
>>> yielded different results than
>>> ```
>>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>>> ```
>>> which it does under this model.
>> 
>> (I think this how it works... semantically, anyway) Since the upper bound 
>> isn't specified, it's inferred from the context.
>> 
>> In the first case, the context is as an index into an array, so the upper 
>> bound is inferred to be the last valid index.
>> 
>> In the second case, there is no context, so it goes to Int.max. Then, after 
>> the "wrong" context has been established, you try to index an array with 
>> numbers from the too-large range.
>> 
>> Semantically speaking, they're pretty different operations. Why is it 
>> surprising that they have different results?
>> 
>> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
>> Jaden and others have pointed out a real semantic issue.
>> 
>> A range is, to put it simply, the "stuff" between two end points. A "range 
>> with no upper bound" _has to be_ one that continues forever. The upper bound 
>> _must_ be infinity.
> 
> Depends… Swift doesn’t allow partial initializations, and neither the 
> `.endIndex` nor the `.upperBound` properties of a `Range` are optional. From 
> a strictly syntactic PoV, a "Range without an upperBound” can’t exist without 
> getting into undefined behavior territory.
> 
> Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
> with an open upper bracket. If you write “[x, ∞]”, with a closed upper 
> bracket, that’s kind of a meaningless statement. I would argue that if we’re 
> going to represent that “infinite” range, the closest Swift spelling would be 
> “x..<“. That leaves the mathematically undefined notation of “[x, ∞]”, 
> spelled as "x…” in Swift, free to let us have “x…” or “…x” (which by similar 
> reasoning can’t mean "(∞, x]”) return one of these:
> enum IncompleteRange {
> case upperValue(T)
> case lowerValue(T)
> }
> which we could then pass to the subscript function of a collection to create 
> the actual Range like this:
> extension Collection {
> subscript(_ ir: IncompleteRange) -> SubSequence {
> switch ir {
> case .lowerValue(let lower): return self[lower ..< self.endIndex]
> case .upperValue(let upper): return self[self.startIndex ..< upper]
> }
> }
> }
> 
> I understand that you can do this from a technical perspective. But I'm 
> arguing it's devoid of semantics.  That is, it's a spelling to dress up a 
> number.

It’s not any more devoid of semantics than a partially applied function.  It is 
a number or index with added semantics that it provides a lower (or upper) 
bound on the possible value specified by its type.

> 
> What is such an `IncompleteRange` other than a value of type T? It's not 
> an upper bound or lower bound of anything until it's used to index a 
> collection. Why have a new type (IncompleteRange), a new set of operators 
> (prefix and postfix range operators), and these muddied semantics for 
> something that can be written `subscript(upTo upperBound: Index) -> 
> SubSequence { ... }`? _That_ has unmistakable semantics and requires no new 
> syntax.

Arguing that it adds too much complexity relative to the value it provides is 
reasonable.  The value in this use case is mostly syntactic sugar so it’s 
relatively easy to make the case that it doesn’t cary its weight here.

The value in Ben’s use case is a more composable alternative to `enumerated`.  
I find this to be a reasonably compelling example of the kind of thing a 
partial range might enable.

I also tend to find concise notation important for clarity as long as it isn’t 
obscure or idiosyncratic.  With that in mind, I think I lean in favor of `…` so 
long as we’re confident we won’t regret it if / when we take up variadic 
generics and / or tuple unpacking.

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

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 5:20 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 31, 2017 at 5:04 PM, Matthew Johnson  > wrote:
> 
> I think it’s fair to say that we get to decide on the semantics of postfix 
> `…`.  “a range with no upper bound” is very reasonable, but wouldn’t another 
> reasonable semantics be “all the rest”, meaning that there *is* an upper 
> bound (the greatest possible value).  
> 
> "All the rest" is by itself insufficient so far as semantics: all the rest 
> _of what_? Supposing that our supplied lower bound is an integer, it must be 
> all the rest of the integers. It cannot be all the rest of whatever, where 
> whatever might be a collection that you try to subset with `0...`. (Recall 
> that collections move indices, but indices know nothing about the 
> collections.) It would be exceeding fuzzy for postfix `...` to mean "all the 
> rest of whatever I want it to mean"--that, almost tautologically, has no 
> semantics at all.
> 
> Under the latter semantics, a `for i in 0…` loop would terminate after 
> reaching Int.max.  This is probably not what the user intended and would 
> still crash when used in David’s example, but it’s worth considering.
> 
> OK, I'm borderline fine with `0... == 0...Int.max`. It at least provides some 
> semantics (i.e., we're saying `...` refers to all the rest of the values 
> representable by the type used for the lower bound) [**]. But Jaden's point 
> still stands, since it would only be consistent if `for i in arr[0...]` then 
> traps after `arr.count` just like `for i in arr[0...Int.max]` would do. 
> Otherwise, we really are fudging the semantics.

If we really want to be honest about the information a value produced using 
postfix `…` carries, it is a partial range with only the lower bound specified. 
 This allows us to assign meaning to that partial range using additional 
context: 

* When it is possible to increment Bound directly could be interpreted as an 
(near?) infinite sequence that either terminates or traps when it reaches an 
unrepresentable value.
* When Bound is an index and the partial range is used as a subscript argument 
it can be interpreted to mean “to the end of the collection”.

This still leaves us with an out of bounds crash in David’s example that 
iterates over a partial range.  This is an artifact of `Array` using Int as 
it’s `Index` rather than an opaque type that does not allow users to increment 
it directly rather than using a collection.  

Is the problem in David’s example really that different than the ability to 
directly index an array with any `Int` we want?  It’s not the kind of thing 
that developers would do frequently.  The first time they try it they will get 
a crash and will learn not to do it again.

I’m not necessarily arguing one way or the other.  I’m simply pointing out that 
“partial range” is a perfectly reasonable semantics to consider.

> 
> [**] It is not perfectly consistent semantically because, as was discussed in 
> threads about our numeric protocols, our integer types are supposed to model 
> all integers, not just the ones that happen to be representable. Our model is 
> imperfect because not all integers fit into finite memory, but that's a 
> modeling artifact and not intentional semantics. IIUC, it would be otherwise 
> difficult to give a good accounting of, say, the semantics of addition if 
> arithmetic overflow were an intentional part of the semantics and not an 
> artifact.

I haven’t followed all of the details of the numeric protocol discussions.  
With this in mind, I agree with your proposed semantics of trapping after 
`Int.max` as it sounds more consistent with this intent.

> 
> I’m not sure if you read Ben’s post regarding `enumerated` or not, but he 
> gave the example of `zip(0…, sequence)` as a more general replacement for 
> `enumerated`.  IMO, he makes a pretty strong case for this.
> 
>> 
>> 
>> - Dave Sweeris 
>> 
>> ___
>> 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] Removing enumerated?

2017-01-31 Thread Jonathan Hull via swift-evolution

> On Jan 31, 2017, at 12:46 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
>> // apply alternating view background colors
>> for (i, view) in views.enumerated() {
>> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
>> }
>> 
> 
> This is an interesting one because it highlights something else I think is 
> missing from the std lib: Sequence.cycle, which would make an infinite 
> sequence by repeating a sequence, enabling what I think is probably a 
> readability win in some cases:
> 
> let colors = [bgColor1, bgColor2].cycle
> for (color, view) in zip(colors, views) {
>   view.backgroundColor = color
> }

This is a common enough need for me that I have built a special class for it.  
Here is the code in case it is useful to others trying to do the same thing:
https://gist.github.com/jonhull/b9cd8a50abca16ea49eade2c91edf8a2

At it’s heart, it takes an array (or a single value) and turns it into an 
endless repeating collection.  It also has facilities for random output, and to 
compose with other sources, allowing complex repeating patterns from simple 
sources.  I originally made it for creating fill patterns in a drawing 
framework (e.g. stripes like your example above), but I have found it generally 
useful over time.

Thanks,
Jon___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Haravikk via swift-evolution

> On 31 Jan 2017, at 20:53, Max Moiseev via swift-evolution 
>  wrote:
> 
> Hi Brent,
> 
> Thanks a lot for your suggestions! After having discussed them with Dave, we 
> came up with the following design that I personally like a lot.
> 
> enum Overflowing { case .withOverflow }
> enum FullWidth { case .fullWidth }
> 
> protocol FixedWidthInteger {
>  func adding(_ other: Self, _: Overflowing) -> (partialValue: Self, overflow: 
> ArithmeticOverflow)
>  func subtracting(_ other: Self, _: Overflowing) -> (partialValue: Self, 
> overflow: ArithmeticOverflow)
>  func multiplied(by other: Self, _: Overflowing) -> (partialValue: Self, 
> overflow: ArithmeticOverflow)
>  func divided(by other: Self, _: Overflowing) -> (partialValue: Self, 
> overflow: ArithmeticOverflow)
> 
>  func multiplied(by other: Self, _: FullWidth) -> DoubleWidth
>  func dividing(_ other: DoubleWidth, _: FullWidth) -> (quotient: Self, 
> remainder: Self)
> }
> 
> 
> Call sites would look like:
> 
> x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)
> 
> a little different for the division:
> 
> x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)
> 
> Note the inverse-ness of `dividing`, but the lack of the argument label makes 
> it quite natural.

While I applaud the ingenuity behind this solution, it seems an odd thing to 
do, and I wonder if it's something that might become obsolete in the future?

I mean, since the purpose of this is just to select the correct method 
declaration, then the more "correct" way to do this would be using labelled 
Void arguments, but of course these aren't as neat right now:

protocol FixedWithInteger {
func adding(_ other:Self, withOverflow:Void) -> 
(partialValue:Self, overflow:ArithmeticOverflow)
}

x.add(y, withOverflow:())

This uses the method's label to avoid the need to declare enums purely for 
selection. The problem is of course that the syntax isn't that great because of 
the extraneous :(). It would be better if we could just do x.add(y, 
withOverflow:), but that might be ambiguous because using labels without values 
is how we select labelled functions (e.g- let f = adding(:withOverflow:) would 
select the method).

I'm just wondering if there's a change to labelled void arguments that we could 
make that would allow that style to be used instead? It just feels to me like 
using a labelled Void is the "proper" way to achieve what is needed, and that 
using enums just because it isn't possible right now is something that could 
become obsolete in future.

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


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread David Sweeris via swift-evolution

> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
> 
> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
> > wrote:
> 
> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
> > wrote:
> 
>> I think that is perfectly reasonable, but then it seems weird to be able to 
>> iterate over it (with no upper bound) independently of a collection). It 
>> would surprise me if
>> ```
>> for x in arr[arr.startIndex…] { print(x) }
>> ```
>> yielded different results than
>> ```
>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>> ```
>> which it does under this model.
> 
> (I think this how it works... semantically, anyway) Since the upper bound 
> isn't specified, it's inferred from the context.
> 
> In the first case, the context is as an index into an array, so the upper 
> bound is inferred to be the last valid index.
> 
> In the second case, there is no context, so it goes to Int.max. Then, after 
> the "wrong" context has been established, you try to index an array with 
> numbers from the too-large range.
> 
> Semantically speaking, they're pretty different operations. Why is it 
> surprising that they have different results?
> 
> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
> Jaden and others have pointed out a real semantic issue.
> 
> A range is, to put it simply, the "stuff" between two end points. A "range 
> with no upper bound" _has to be_ one that continues forever. The upper bound 
> _must_ be infinity.

Depends… Swift doesn’t allow partial initializations, and neither the 
`.endIndex` nor the `.upperBound` properties of a `Range` are optional. From a 
strictly syntactic PoV, a "Range without an upperBound” can’t exist without 
getting into undefined behavior territory.

Plus, mathematically speaking, an infinite range would be written "[x, ∞)", 
with an open upper bracket. If you write “[x, ∞]”, with a closed upper bracket, 
that’s kind of a meaningless statement. I would argue that if we’re going to 
represent that “infinite” range, the closest Swift spelling would be “x..<“. 
That leaves the mathematically undefined notation of “[x, ∞]”, spelled as "x…” 
in Swift, free to let us have “x…” or “…x” (which by similar reasoning can’t 
mean "(∞, x]”) return one of these:
enum IncompleteRange {
case upperValue(T)
case lowerValue(T)
}
which we could then pass to the subscript function of a collection to create 
the actual Range like this:
extension Collection {
subscript(_ ir: IncompleteRange) -> SubSequence {
switch ir {
case .lowerValue(let lower): return self[lower ..< self.endIndex]
case .upperValue(let upper): return self[self.startIndex ..< upper]
}
}
}

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


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 5:28 PM, David Sweeris  wrote:

>
> On Jan 31, 2017, at 2:04 PM, Xiaodi Wu  wrote:
>
> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution  evolut...@swift.org> wrote:
>
>>
>> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> I think that is perfectly reasonable, but then it seems weird to be able
>> to iterate over it (with no upper bound) independently of a collection). It
>> would surprise me if
>> ```
>> for x in arr[arr.startIndex…] { print(x) }
>> ```
>> yielded different results than
>> ```
>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>> ```
>> which it does under this model.
>>
>>
>> (I *think* this how it works... semantically, anyway) Since the upper
>> bound isn't specified, it's inferred from the context.
>>
>> In the first case, the context is as an index into an array, so the upper
>> bound is inferred to be the last valid index.
>>
>> In the second case, there is no context, so it goes to Int.max. Then,
>> *after* the "wrong" context has been established, you try to index an
>> array with numbers from the too-large range.
>>
>> Semantically speaking, they're pretty different operations. Why is it
>> surprising that they have different results?
>>
>
> I must say, I was originally rather fond of `0...` as a spelling, but IMO,
> Jaden and others have pointed out a real semantic issue.
>
> A range is, to put it simply, the "stuff" between two end points. A "range
> with no upper bound" _has to be_ one that continues forever. The upper
> bound _must_ be infinity.
>
>
> Depends… Swift doesn’t allow partial initializations, and neither the
> `.endIndex` nor the `.upperBound` properties of a `Range` are optional.
> From a strictly syntactic PoV, a "Range without an upperBound” can’t exist
> without getting into undefined behavior territory.
>
> Plus, mathematically speaking, an infinite range would be written "[x,
> ∞)", with an open upper bracket. If you write “[x, ∞]”, with a *closed*
> upper bracket, that’s kind of a meaningless statement. I would argue that
> if we’re going to represent that “infinite” range, the closest Swift
> spelling would be “x..<“. That leaves the mathematically undefined notation
> of “[x, ∞]”, spelled as "x…” in Swift, free to let us have “x…” or “…x”
> (which by similar reasoning can’t mean "(∞, x]”) return one of these:
>
> enum IncompleteRange {
> case upperValue(T)
> case lowerValue(T)
> }
>
> which we could then pass to the subscript function of a collection to
> create the actual Range like this:
>
> extension Collection {
> subscript(_ ir: IncompleteRange) -> SubSequence {
> switch ir {
> case .lowerValue(let lower): return self[lower ..< self.endIndex]
> case .upperValue(let upper): return self[self.startIndex ..<
> upper]
> }
> }
> }
>
>
I understand that you can do this from a technical perspective. But I'm
arguing it's devoid of semantics. That is, it's a spelling to dress up a
number.

What is such an `IncompleteRange` other than a value of type T? It's not
an upper bound or lower bound of anything until it's used to index a
collection. Why have a new type (IncompleteRange), a new set of
operators (prefix and postfix range operators), and these muddied semantics
for something that can be written `subscript(upTo upperBound: Index) ->
SubSequence { ... }`? _That_ has unmistakable semantics and requires no new
syntax.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Xiaodi Wu via swift-evolution
On Tue, Jan 31, 2017 at 5:04 PM, Matthew Johnson 
wrote:

>
> I think it’s fair to say that we get to decide on the semantics of postfix
> `…`.  “a range with no upper bound” is very reasonable, but wouldn’t
> another reasonable semantics be “all the rest”, meaning that there *is* an
> upper bound (the greatest possible value).
>

"All the rest" is by itself insufficient so far as semantics: all the rest
_of what_? Supposing that our supplied lower bound is an integer, it must
be all the rest of the integers. It cannot be all the rest of whatever,
where whatever might be a collection that you try to subset with `0...`.
(Recall that collections move indices, but indices know nothing about the
collections.) It would be exceeding fuzzy for postfix `...` to mean "all
the rest of whatever I want it to mean"--that, almost tautologically, has
no semantics at all.

Under the latter semantics, a `for i in 0…` loop would terminate after
> reaching Int.max.  This is probably not what the user intended and would
> still crash when used in David’s example, but it’s worth considering.
>

OK, I'm borderline fine with `0... == 0...Int.max`. It at least provides
some semantics (i.e., we're saying `...` refers to all the rest of the
values representable by the type used for the lower bound) [**]. But
Jaden's point still stands, since it would only be consistent if `for i in
arr[0...]` then traps after `arr.count` just like `for i in
arr[0...Int.max]` would do. Otherwise, we really are fudging the semantics.

[**] It is not perfectly consistent semantically because, as was discussed
in threads about our numeric protocols, our integer types are supposed to
model all integers, not just the ones that happen to be representable. Our
model is imperfect because not all integers fit into finite memory, but
that's a modeling artifact and not intentional semantics. IIUC, it would be
otherwise difficult to give a good accounting of, say, the semantics of
addition if arithmetic overflow were an intentional part of the semantics
and not an artifact.

I’m not sure if you read Ben’s post regarding `enumerated` or not, but he
> gave the example of `zip(0…, sequence)` as a more general replacement for
> `enumerated`.  IMO, he makes a pretty strong case for this.
>
>
>
> - Dave Sweeris
>>
>> ___
>> 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] Default Generic Arguments

2017-01-31 Thread Xiaodi Wu via swift-evolution
I have concerns about these revisions. It seems you've entirely rejected
all the options that Alexis has laid out very clearly, and instead you've
come up with your own rules which are backwards-incompatible with Swift 3.

For instance, the rule "No type inference will happen in type declarations"
is source-breaking, because type inference currently happens in type
declarations. You would break every instance of `let foo: Optional = 42`.

I would urge you to incorporate Alexis's very clear analysis and then adopt
one of the options he laid out, i.e., either "prefer user" or "do what I
mean." Alternatively, if you like none of his options, I believe that
requiring `<>` to be appended for entirely default arguments would avoid
the issue altogether. Or, if you don't even want to require that, you can
push the whole problem down the road by specifying that, for now, the first
generic type cannot have a default. We can then relax the rules later.


On Tue, Jan 31, 2017 at 3:15 PM, Srđan Rašić  wrote:

> I updated the proposal with the things we discussed so far. Have to do
> some more polishing, but feel free to throw your critique of what I have so
> far.
>
> On Sat, Jan 28, 2017 at 1:32 AM, Xiaodi Wu  wrote:
>
>> Oh, it's precisely my confidence that a good error message can be devised
>> which makes me ponder whether "prefer user" is the ideal rule. Having a
>> stricter rule isn't necessarily bad if the error message makes it easy to
>> remedy.
>>
>> In your example, "prefer user" would object at the line where you make
>> your Something. I think that makes for a much cleaner error. By contrast,
>> DWIM necessitates the acrobatics you show above, where the compiler will
>> have to keep track of a defaulted type for each variable as long as it's in
>> scope and propose remote fix-its at the declaration site based on how it's
>> later used. Now what happens if there's an action() that takes only
>> Something arguments and an action2() that takes only Something
>> arguments? Will you have an alternating cycle of fix-its that don't fix the
>> problem?
>>
>>
>> On Fri, Jan 27, 2017 at 18:07 Karl Wagner  wrote:
>>
>>>
>>> On 27 Jan 2017, at 01:30, Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
>>> Cool, thanks--that makes sense.
>>>
>>> Personally, although DWIM is appealing, I think if we are to go all-out
>>> on your stance that "adding a default to an existing type parameter should
>>> be a strict source-breaking change," then "prefer user" is the one rule
>>> that maximally clarifies the scenario. With that rule, in the evolution
>>> scenarios that I brought up, either the user-specified default and the
>>> inferred literal type line up perfectly or it is guaranteed to be
>>> source-breaking. IMO, that consistency would bring more clarity than DWIM,
>>> which might prompt a user to be confused why sometimes the compiler "gets
>>> it" and other times it doesn’t.
>>>
>>>
>>> I’m not sure, I think it will be easy enough for users to figure out
>>> where the problem is because it will create a type-mismatch.
>>> When type mismatches occur, the only place to look is the variable
>>> definition, because that is where the type is defined.
>>>
>>> This is such a narrow case that I’m sure we can provide good diagnostics
>>> for it. The pattern could be:
>>>
>>> - A generic parameter mismatch (i.e. trying to use a value of type
>>> MyType where type MyType is expected), and
>>> - X and Y are both {Whatever}LiteralConvertible, and
>>> - X is the default type bound to that parameter, and
>>> - the value was initialised using a {Whatever} literal, where an
>>> instance of the parameter was expected
>>>
>>> In that case, we could introduce a simple fix-it: replacing one of the
>>> literal values with "(literal as Y)”
>>>
>>> for example:
>>>
>>> struct 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 4:04 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Tue, Jan 31, 2017 at 3:36 PM, David Sweeris via swift-evolution 
> > wrote:
> 
> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
> > wrote:
> 
>> I think that is perfectly reasonable, but then it seems weird to be able to 
>> iterate over it (with no upper bound) independently of a collection). It 
>> would surprise me if
>> ```
>> for x in arr[arr.startIndex…] { print(x) }
>> ```
>> yielded different results than
>> ```
>> for i in arr.startIndex… { print(arr[i]) } // CRASH
>> ```
>> which it does under this model.
> 
> (I think this how it works... semantically, anyway) Since the upper bound 
> isn't specified, it's inferred from the context.
> 
> In the first case, the context is as an index into an array, so the upper 
> bound is inferred to be the last valid index.
> 
> In the second case, there is no context, so it goes to Int.max. Then, after 
> the "wrong" context has been established, you try to index an array with 
> numbers from the too-large range.
> 
> Semantically speaking, they're pretty different operations. Why is it 
> surprising that they have different results?
> 
> I must say, I was originally rather fond of `0...` as a spelling, but IMO, 
> Jaden and others have pointed out a real semantic issue.
> 
> A range is, to put it simply, the "stuff" between two end points. A "range 
> with no upper bound" _has to be_ one that continues forever.
> The upper bound _must_ be infinity. What Dave Abrahams has described does not 
> have the semantics of a range with no upper bound. He's describing a 
> standalone lower bound with no "stuff." It stands to reason that such a type 
> should not be a sequence at all. But we already use particular types for 
> upper and lower bounds that aren't sequences, and they're plain numeric 
> types. Therefore I'd conclude that `arr[upTo: i]` is the most consistent 
> spelling. It also yields the sensible result that `arr[from: i][upTo: j] == 
> arr[upTo: j][from: i] == arr[i.. 
> If `0...` is to have the semantics of a range with no upper bound, I would 
> expect `for i in 0...` to be an infinite loop, equivalent to `for i in 
> stride(from: 0, through: Int.max, by: 1)` for Int.max+1 iterations and then 
> trapping. Which is, well, silly. I'm coming around to thinking that `0...` is 
> a sexy notation for something we don't need and a poor notation for something 
> that's more cleanly expressed by plain numbers.


I think it’s fair to say that we get to decide on the semantics of postfix `…`. 
 “a range with no upper bound” is very reasonable, but wouldn’t another 
reasonable semantics be “all the rest”, meaning that there *is* an upper bound 
(the greatest possible value).  

Under the latter semantics, a `for i in 0…` loop would terminate after reaching 
Int.max.  This is probably not what the user intended and would still crash 
when used in David’s example, but it’s worth considering.

I’m not sure if you read Ben’s post regarding `enumerated` or not, but he gave 
the example of `zip(0…, sequence)` as a more general replacement for 
`enumerated`.  IMO, he makes a pretty strong case for this.

> 
> 
> - Dave Sweeris 
> 
> ___
> 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] Strings in Swift 4

2017-01-31 Thread David Sweeris via swift-evolution

> On Jan 31, 2017, at 11:32, Jaden Geller via swift-evolution 
>  wrote:
> 
> I think that is perfectly reasonable, but then it seems weird to be able to 
> iterate over it (with no upper bound) independently of a collection). It 
> would surprise me if
> ```
> for x in arr[arr.startIndex…] { print(x) }
> ```
> yielded different results than
> ```
> for i in arr.startIndex… { print(arr[i]) } // CRASH
> ```
> which it does under this model.

(I think this how it works... semantically, anyway) Since the upper bound isn't 
specified, it's inferred from the context.

In the first case, the context is as an index into an array, so the upper bound 
is inferred to be the last valid index.

In the second case, there is no context, so it goes to Int.max. Then, after the 
"wrong" context has been established, you try to index an array with numbers 
from the too-large range.

Semantically speaking, they're pretty different operations. Why is it 
surprising that they have different results?

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


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Jacob Bandes-Storch via swift-evolution
Cute. Reminds me of C++ STL's struct tags: http://en.cppreference.
com/w/cpp/utility/piecewise_construct_t
http://en.cppreference.com/w/cpp/iterator/iterator_tags

On Tue, Jan 31, 2017 at 12:53 PM, Max Moiseev via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi Brent,
>
> Thanks a lot for your suggestions! After having discussed them with Dave,
> we came up with the following design that I personally like a lot.
>
> enum Overflowing { case .withOverflow }
> enum FullWidth { case .fullWidth }
>
> protocol FixedWidthInteger {
>   func adding(_ other: Self, _: Overflowing) -> (partialValue: Self,
> overflow: ArithmeticOverflow)
>   func subtracting(_ other: Self, _: Overflowing) -> (partialValue: Self,
> overflow: ArithmeticOverflow)
>   func multiplied(by other: Self, _: Overflowing) -> (partialValue: Self,
> overflow: ArithmeticOverflow)
>   func divided(by other: Self, _: Overflowing) -> (partialValue: Self,
> overflow: ArithmeticOverflow)
>
>   func multiplied(by other: Self, _: FullWidth) -> DoubleWidth
>   func dividing(_ other: DoubleWidth, _: FullWidth) -> (quotient:
> Self, remainder: Self)
> }
>
>
> Call sites would look like:
>
> x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)
>
> a little different for the division:
>
> x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)
>
> Note the inverse-ness of `dividing`, but the lack of the argument label
> makes it quite natural.
>
>
> > 2. There is no quotient-and-remainder-with-overflow, either regular or
> double-width. Can we do that?
> What will the partialValue equivalent be in case of overflow in
> overflowing quotient+remainder division?
> >
> > 3. "Overflow" is not really a good description of what's happening in
> division; the value is undefined, not overflowing. Is there a better way to
> express this?
> Division by 0 is not overflowing, true, but Int.min / (-1) is.
> >
> > 4. For that matter, even non-fixed-width division can "overflow"; should
> that concept be hoisted higher up the protocol hierarchy?
> In my head, overflow is a notion related to fixed sized types. You simply
> don’t have enough room to represent certain values. Following this line of
> thought, binary integer is not bounded, and can grow at will. So
> FixedWidthInteger looks like the right place for overflowing operations.
> And if we decide to not consider division by 0 an overflow, the model seems
> quite consistent.
>
>
> > On Jan 30, 2017, at 7:55 PM, Brent Royal-Gordon 
> wrote:
> >
> >> On Jan 30, 2017, at 11:31 AM, Max Moiseev  wrote:
> >>
> >> doubleWidthDivide should not return a DoubleWidth for two reasons:
> >> 1. The components of it’s return type are not high and low, but are
> quotient and remainder instead.
> >> 2. In DoubleWidth high is T and low is T.Magnitude, which is not the
> case for quotient and remainder.
> >
> > You're right about the return value; for `doubleWidthDivide(_:_:)`, I
> was thinking about changing the dividend. Specifically, I'm thinking we
> should change these to:
> >
> >   static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) ->
> DoubleWidth
> >   static func doubleWidthDivide(_ lhs: DoubleWidth, _ rhs:
> Self) -> (quotient: Self, remainder: Self)
> >
> > I'm also thinking a little bit about spelling of these operations. I'd
> *love* to be able to call them `*` and `/` and let the type system sort
> things out, but that would cause problems, especially for multiply (since
> the return value is the only thing different from a normal `*`). We could
> invent a new operator, but that would be a bit much. Could these be simply
> `multiply` and `divide`, and we'll permit the `DoubleWidth`
> parameter/return type to explain itself?
> >
> > I'm also thinking the second parameter should be labeled `by`, since
> that's the way people talk about these operations. Applying both of these
> suggestions, we'd get:
> >
> >   static func multiply(_ lhs: Self, by rhs: Self) ->
> DoubleWidth
> >   static func divide(_ lhs: DoubleWidth, by rhs: Self) ->
> (quotient: Self, remainder: Self)
> >
> >   let x = Int.multiply(a, by: b)
> >   let (aʹ, r) = Int.divide(x, by: b)
> >   assert(a == aʹ)
> >   assert(r == 0)
> >
> > Should the standard library provide extensions automatic definitions of
> multiplication and division in terms of their double-width equivalents?
> >
> >   extension FixedWidthInteger {
> >   func multipliedWithOverflow(by other: Self) ->
> (partialValue: Self, overflow: ArithmeticOverflow) {
> >   let doubledResult = Self.multiply(self, by: other)
> >   let overflowed = doubledResult.high !=
> (doubledResult < 0 ? -1 : 0)
> >   return (Self(bitPattern:
> doubledResult.lowerValue), overflowed ? .overflowed : .none)
> >   }
> >
> >   func quotientAndRemainder(dividingBy other: Self) ->
> (quotient: Self, remainder: 

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Dave Abrahams via swift-evolution

on Tue Jan 31 2017, Jaden Geller  wrote:

 On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
  wrote:
 
 Why should that be out-of-bounds?  Whether it is out-of-bounds would
 depend on what items is.  If it's an array, that should be equivalent to
 
  let x = items[items.startIndex..>> 
>>> It seems to me that `items[0…]` would be equivalent to
>>> `items[0…Int.max]` if we’re going to treat `0…` as an “infinite"
>>> range, no? Otherwise, we’re either giving subscript of InfiniteRange
>>> types special behavior or we’re making subscript ignore past-the-end
>>> indices; `”hello”.characters[0…10]` would need to return the same as
>>> “hello”.characters[0…4]` to be consistent.
>> 
>> What is it they say about “a foolish consistency?” ;-)
>> 
>> More seriously, I think you may be viewing these ranges the wrong way
>> around.
>> 
>>0...
>> 
>> is not a range with an upper bound of infinity (which is, after all, not
>> a number!); it's a range with *no* upper bound.  When you use the range
>> for slicing, the collection substitutes its own upper bound.
>> 
>> HTH,
>> 
>> -- 
>> -Dave
>
> I think that is perfectly reasonable, but then it seems weird to be
> able to iterate over it (with no upper bound) independently of a
> collection). It would surprise me if
> ```
> for x in arr[arr.startIndex…] { print(x) }
> ```
> yielded different results than
> ```
> for i in arr.startIndex… { print(arr[i]) } // CRASH
> ```
> which it does under this model.

That makes perfect sense to me.  The first example visually shows the range
being constrained by the bounds of `arr`, whereas in the second example
it is not.

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 2:46 PM, Ben Cohen  wrote:
> 
>> 
>> On Jan 31, 2017, at 12:18 PM, Matthew Johnson > > wrote:
>> 
>>> 
>>> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>>> > wrote:
>>> 
>>> I think whether enumerated() is justified as a method on Sequence is one 
>>> example of a wider question which definitely needs some discussion, which 
>>> is: where should the standard library draw the line in providing 
>>> convenience functions that can easily be composed from other functions in 
>>> the std lib? Here’s another example: 
>>> 
>>> SE-100 
>>> 
>>>  is a proposal to add an init to Dictionary from a sequence of key/value 
>>> pairs. It’s a commonly requested feature, and IMO much needed and should be 
>>> added as soon as we move to the appropriate phase in Swift’s evolution. 
>>> 
>>> Another commonly requested Dictionary feature is similar: add a 
>>> Dictionary.init that takes a sequence, and a closure that maps that 
>>> sequence to keys. This is useful, for example, when you have a sequence of 
>>> objects that you frequently need to index into via one property on those 
>>> objects, so you want to build a fast lookup cache using that property.
>>> 
>>> Now, if we implement SE-100, that second request can be easily composed. It 
>>> would be something like Dictionary(sequence.lazy.map { (key: 
>>> $0.someProperty, value: $0) } )
>>> 
>>> Some people look at that line of code and think sure, that’s what I’d do 
>>> and it’s easy enough that the second helper shouldn’t be added as it’s 
>>> superfluous. Others look at it and say that it is unreadable clever-code FP 
>>> nonsense, and we should just add the helper method because most programmers 
>>> wouldn’t be able to read or write that easily.
>>> 
>>> As we expand (and maybe contract :) the standard library, this kind of 
>>> question comes up a lot, so it is worth setting out some criteria for 
>>> judging these
>>> “helper” methods. Here’s my take on such a list (warning: objectivity and 
>>> subjectivity blended together in the below).
>> 
>> This is a great analysis and list of criteria.  Thanks for putting this 
>> together Ben!
>> 
>>> 
>>> 1. Is it truly a frequent operation?
>>> 
>>> The operation needs to carry its weight. Even once we have ABI stability, 
>>> so the size of the std lib becomes less of a concern as it could ship as 
>>> part of the OS, we still need to keep helper method growth under control. 
>>> APIs bristling with methods like an over-decorated Xmas tree are bad for 
>>> usability. As mentioned in the String manifesto, String+Foundation 
>>> currently has over 200 methods/properties. Helpers are no good if you can’t 
>>> find them to use them.
>>> 
>>> Someone mentioned that they actually don’t find themselves using 
>>> enumerated() all that often. I suspect enumerated in its current form isn’t 
>>> all that useful. In a quick (and non-scientific) review of search results 
>>> for its use on GitHub, nearly all the examples I see of it are either 1) 
>>> misuse – see more below, or 2) use of it to perform the equivalent of 
>>> in-place map where the index is used to subscript into the array and 
>>> replace it with a transformed element.
>>> 
>>> I think the std lib needs an in-place map, and if enumerated() is removed, 
>>> this one most-common use case should be added at the same time.
>> 
>> I just did a quick search in a couple of projects and found a handful of 
>> good examples of valid uses of `enumerated`.  I have simplified the examples 
>> from real world code, but I think they demonstrate the kinds of things this 
>> is good for.
>> 
>> // only show the first 5 views
>> for (i, view) in views.enumerated() {
>> view.hidden = i >= 5
>> }
>> 
> 
> Interesting that several of these rely on reference types as elements. This 
> does make the loops a lot simpler. In-place amendment of an array would be 
> messier, and the combination with zip definitely pushes back against my 
> notion that an in-place map would be a useful alternative (since you couldn’t 
> mutate the mutable half of the zipped collection in-place without us jumping 
> through some hoops).
> 
> 
>> // apply alternating view background colors
>> for (i, view) in views.enumerated() {
>> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
>> }
>> 
> 
> This is an interesting one because it highlights something else I think is 
> missing from the std lib: Sequence.cycle, which would make an infinite 
> sequence by repeating a sequence, enabling what I think is probably a 
> readability win in some cases:
> 
> let colors = [bgColor1, bgColor2].cycle
> for (color, view) in zip(colors, views) {
>   view.backgroundColor = color
> }
> 
> Also i%2 used as a boolean – 

Re: [swift-evolution] Default Generic Arguments

2017-01-31 Thread Srđan Rašić via swift-evolution
I updated the proposal with the things we discussed so far. Have to do some
more polishing, but feel free to throw your critique of what I have so far.

On Sat, Jan 28, 2017 at 1:32 AM, Xiaodi Wu  wrote:

> Oh, it's precisely my confidence that a good error message can be devised
> which makes me ponder whether "prefer user" is the ideal rule. Having a
> stricter rule isn't necessarily bad if the error message makes it easy to
> remedy.
>
> In your example, "prefer user" would object at the line where you make
> your Something. I think that makes for a much cleaner error. By contrast,
> DWIM necessitates the acrobatics you show above, where the compiler will
> have to keep track of a defaulted type for each variable as long as it's in
> scope and propose remote fix-its at the declaration site based on how it's
> later used. Now what happens if there's an action() that takes only
> Something arguments and an action2() that takes only Something
> arguments? Will you have an alternating cycle of fix-its that don't fix the
> problem?
>
>
> On Fri, Jan 27, 2017 at 18:07 Karl Wagner  wrote:
>
>>
>> On 27 Jan 2017, at 01:30, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Cool, thanks--that makes sense.
>>
>> Personally, although DWIM is appealing, I think if we are to go all-out
>> on your stance that "adding a default to an existing type parameter should
>> be a strict source-breaking change," then "prefer user" is the one rule
>> that maximally clarifies the scenario. With that rule, in the evolution
>> scenarios that I brought up, either the user-specified default and the
>> inferred literal type line up perfectly or it is guaranteed to be
>> source-breaking. IMO, that consistency would bring more clarity than DWIM,
>> which might prompt a user to be confused why sometimes the compiler "gets
>> it" and other times it doesn’t.
>>
>>
>> I’m not sure, I think it will be easy enough for users to figure out
>> where the problem is because it will create a type-mismatch.
>> When type mismatches occur, the only place to look is the variable
>> definition, because that is where the type is defined.
>>
>> This is such a narrow case that I’m sure we can provide good diagnostics
>> for it. The pattern could be:
>>
>> - A generic parameter mismatch (i.e. trying to use a value of type
>> MyType where type MyType is expected), and
>> - X and Y are both {Whatever}LiteralConvertible, and
>> - X is the default type bound to that parameter, and
>> - the value was initialised using a {Whatever} literal, where an instance
>> of the parameter was expected
>>
>> In that case, we could introduce a simple fix-it: replacing one of the
>> literal values with "(literal as Y)”
>>
>> for example:
>>
>> struct 

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Max Moiseev via swift-evolution
Hi Brent,

Thanks a lot for your suggestions! After having discussed them with Dave, we 
came up with the following design that I personally like a lot.

enum Overflowing { case .withOverflow }
enum FullWidth { case .fullWidth }

protocol FixedWidthInteger {
  func adding(_ other: Self, _: Overflowing) -> (partialValue: Self, overflow: 
ArithmeticOverflow)
  func subtracting(_ other: Self, _: Overflowing) -> (partialValue: Self, 
overflow: ArithmeticOverflow)
  func multiplied(by other: Self, _: Overflowing) -> (partialValue: Self, 
overflow: ArithmeticOverflow)
  func divided(by other: Self, _: Overflowing) -> (partialValue: Self, 
overflow: ArithmeticOverflow)

  func multiplied(by other: Self, _: FullWidth) -> DoubleWidth
  func dividing(_ other: DoubleWidth, _: FullWidth) -> (quotient: Self, 
remainder: Self)
}


Call sites would look like:

x.multiplied(by: y, .withOverflow) and x.multiplied(by: y, .fullWidth)

a little different for the division:

x.divided(by: y, .withOverflow) and y.dividing(x, .fullWidth)

Note the inverse-ness of `dividing`, but the lack of the argument label makes 
it quite natural.


> 2. There is no quotient-and-remainder-with-overflow, either regular or 
> double-width. Can we do that?
What will the partialValue equivalent be in case of overflow in overflowing 
quotient+remainder division?
> 
> 3. "Overflow" is not really a good description of what's happening in 
> division; the value is undefined, not overflowing. Is there a better way to 
> express this?
Division by 0 is not overflowing, true, but Int.min / (-1) is.
> 
> 4. For that matter, even non-fixed-width division can "overflow"; should that 
> concept be hoisted higher up the protocol hierarchy?
In my head, overflow is a notion related to fixed sized types. You simply don’t 
have enough room to represent certain values. Following this line of thought, 
binary integer is not bounded, and can grow at will. So FixedWidthInteger looks 
like the right place for overflowing operations. And if we decide to not 
consider division by 0 an overflow, the model seems quite consistent.


> On Jan 30, 2017, at 7:55 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Jan 30, 2017, at 11:31 AM, Max Moiseev  wrote:
>> 
>> doubleWidthDivide should not return a DoubleWidth for two reasons:
>> 1. The components of it’s return type are not high and low, but are quotient 
>> and remainder instead.
>> 2. In DoubleWidth high is T and low is T.Magnitude, which is not the case 
>> for quotient and remainder.
> 
> You're right about the return value; for `doubleWidthDivide(_:_:)`, I was 
> thinking about changing the dividend. Specifically, I'm thinking we should 
> change these to:
> 
>   static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) -> 
> DoubleWidth
>   static func doubleWidthDivide(_ lhs: DoubleWidth, _ rhs: Self) -> 
> (quotient: Self, remainder: Self)
> 
> I'm also thinking a little bit about spelling of these operations. I'd *love* 
> to be able to call them `*` and `/` and let the type system sort things out, 
> but that would cause problems, especially for multiply (since the return 
> value is the only thing different from a normal `*`). We could invent a new 
> operator, but that would be a bit much. Could these be simply `multiply` and 
> `divide`, and we'll permit the `DoubleWidth` parameter/return type to explain 
> itself?
> 
> I'm also thinking the second parameter should be labeled `by`, since that's 
> the way people talk about these operations. Applying both of these 
> suggestions, we'd get:
> 
>   static func multiply(_ lhs: Self, by rhs: Self) -> DoubleWidth
>   static func divide(_ lhs: DoubleWidth, by rhs: Self) -> 
> (quotient: Self, remainder: Self)
>   
>   let x = Int.multiply(a, by: b)
>   let (aʹ, r) = Int.divide(x, by: b)
>   assert(a == aʹ)
>   assert(r == 0)
> 
> Should the standard library provide extensions automatic definitions of 
> multiplication and division in terms of their double-width equivalents?
> 
>   extension FixedWidthInteger {
>   func multipliedWithOverflow(by other: Self) -> (partialValue: 
> Self, overflow: ArithmeticOverflow) {
>   let doubledResult = Self.multiply(self, by: other)
>   let overflowed = doubledResult.high != (doubledResult < 
> 0 ? -1 : 0)
>   return (Self(bitPattern: doubledResult.lowerValue), 
> overflowed ? .overflowed : .none)
>   }
>   
>   func quotientAndRemainder(dividingBy other: Self) -> (quotient: 
> Self, remainder: Self) {
>   precondition(other != 0, "Divide by zero")
>   return Self.divide(DoubleWidth(self), by: other)
>   }
>   
>   func dividedWithOverflow(by other: Self) -> (partialValue: 
> Self, overflow: ArithmeticOverflow) {
>   guard other != 0 else { return (self, 

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ben Cohen via swift-evolution

> On Jan 31, 2017, at 12:18 PM, Matthew Johnson  wrote:
> 
>> 
>> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>> > wrote:
>> 
>> I think whether enumerated() is justified as a method on Sequence is one 
>> example of a wider question which definitely needs some discussion, which 
>> is: where should the standard library draw the line in providing convenience 
>> functions that can easily be composed from other functions in the std lib? 
>> Here’s another example: 
>> 
>> SE-100 
>> 
>>  is a proposal to add an init to Dictionary from a sequence of key/value 
>> pairs. It’s a commonly requested feature, and IMO much needed and should be 
>> added as soon as we move to the appropriate phase in Swift’s evolution. 
>> 
>> Another commonly requested Dictionary feature is similar: add a 
>> Dictionary.init that takes a sequence, and a closure that maps that sequence 
>> to keys. This is useful, for example, when you have a sequence of objects 
>> that you frequently need to index into via one property on those objects, so 
>> you want to build a fast lookup cache using that property.
>> 
>> Now, if we implement SE-100, that second request can be easily composed. It 
>> would be something like Dictionary(sequence.lazy.map { (key: 
>> $0.someProperty, value: $0) } )
>> 
>> Some people look at that line of code and think sure, that’s what I’d do and 
>> it’s easy enough that the second helper shouldn’t be added as it’s 
>> superfluous. Others look at it and say that it is unreadable clever-code FP 
>> nonsense, and we should just add the helper method because most programmers 
>> wouldn’t be able to read or write that easily.
>> 
>> As we expand (and maybe contract :) the standard library, this kind of 
>> question comes up a lot, so it is worth setting out some criteria for 
>> judging these
>> “helper” methods. Here’s my take on such a list (warning: objectivity and 
>> subjectivity blended together in the below).
> 
> This is a great analysis and list of criteria.  Thanks for putting this 
> together Ben!
> 
>> 
>> 1. Is it truly a frequent operation?
>> 
>> The operation needs to carry its weight. Even once we have ABI stability, so 
>> the size of the std lib becomes less of a concern as it could ship as part 
>> of the OS, we still need to keep helper method growth under control. APIs 
>> bristling with methods like an over-decorated Xmas tree are bad for 
>> usability. As mentioned in the String manifesto, String+Foundation currently 
>> has over 200 methods/properties. Helpers are no good if you can’t find them 
>> to use them.
>> 
>> Someone mentioned that they actually don’t find themselves using 
>> enumerated() all that often. I suspect enumerated in its current form isn’t 
>> all that useful. In a quick (and non-scientific) review of search results 
>> for its use on GitHub, nearly all the examples I see of it are either 1) 
>> misuse – see more below, or 2) use of it to perform the equivalent of 
>> in-place map where the index is used to subscript into the array and replace 
>> it with a transformed element.
>> 
>> I think the std lib needs an in-place map, and if enumerated() is removed, 
>> this one most-common use case should be added at the same time.
> 
> I just did a quick search in a couple of projects and found a handful of good 
> examples of valid uses of `enumerated`.  I have simplified the examples from 
> real world code, but I think they demonstrate the kinds of things this is 
> good for.
> 
> // only show the first 5 views
> for (i, view) in views.enumerated() {
> view.hidden = i >= 5
> }
> 

Interesting that several of these rely on reference types as elements. This 
does make the loops a lot simpler. In-place amendment of an array would be 
messier, and the combination with zip definitely pushes back against my notion 
that an in-place map would be a useful alternative (since you couldn’t mutate 
the mutable half of the zipped collection in-place without us jumping through 
some hoops).


> // apply alternating view background colors
> for (i, view) in views.enumerated() {
> view.backgroundColor = i % 2 ? bgColor1 : bgColor2
> }
> 

This is an interesting one because it highlights something else I think is 
missing from the std lib: Sequence.cycle, which would make an infinite sequence 
by repeating a sequence, enabling what I think is probably a readability win in 
some cases:

let colors = [bgColor1, bgColor2].cycle
for (color, view) in zip(colors, views) {
view.backgroundColor = color
}

Also i%2 used as a boolean – what language is this? :)

> // linear layout
> for (i, view) in views.enumerated() {
>let x = width * CGFloat(i)
>view.frame = CGRect(x: x, y: 0, width: width, height: height)
> }
> 
> // deriving locations for an equally 

Re: [swift-evolution] Initializers

2017-01-31 Thread John McCall via swift-evolution
> On Jan 31, 2017, at 3:13 PM, Victor Petrescu  
> wrote:
> @John McCall The expense at runtime issue of course. The fact that I need to 
> add one more line would never bother me enough to bother a few hundreds ppl 
> in turn :).

Are you under the impression that the compiler is unable to inline the 
super.init() call?

John.

> 
> On Tue, Jan 31, 2017 at 9:51 PM, John McCall  > wrote:
>> On Jan 28, 2017, at 1:07 PM, Victor Petrescu via swift-evolution 
>> > wrote:
>> Hello,
>> 
>> My name is Victor, been a developer (C, delphi, php, java, js) for the last 
>> 10 years or so and lately I had the chance to try swift. I have a 
>> suggestion/question regarding initializers.
>> 
>> Sidenote: If this is not the correct mailing list for this can you please 
>> redirect me to the right place?
>> 
>> Consider the following 2 classes and code:
>> 
>> class A {
>>  var x:Int
>> 
>>  init() {
>>  x = 1
>>  }
>> }
>> 
>> class B : A {
>> override init() {
>>  super.init() // Swift FORCES this call
>>  x = 2
>> }
>> }
>> 
>> var a:B
>> for i in 0... {
>> a = B()  // Whatever... some code that inits B.
>> }
>> 
>> This results in  x = 1 then  x = 2... the x = 1 being 
>> totally useless in this particular case.
>> 
>> In this case, if you don't make the super init you get a compile error.
>> 
>> Now... I see the use of this. It ensure that all members are initialized. 
>> For example if A had a private variable (another strange choice here with 
>> what private means in swift but I haven't thought on it yet so... maybe is a 
>> cool choice), the B init could not initialize it. I also understand that the 
>> cases when you need this minor performance gain are rather rare (but they do 
>> still exist). So I guess the choice for the super.init() had that reasoning.
>> 
>> Still... my suggestion would be to give a warning, maybe force a key word 
>> before the init (like iKnowWhatImDoing init() {}), THEN in case vars are 
>> still not inited give a runtime error (afaik Objective C for example gives a 
>> warning). That ensures everything is ok and also allows programmers that 
>> have strange cases to treat them accordingly.
>> 
>> Anyway... that would be my suggestion. Maybe this was discussed before 
>> also... If this was discussed before can you please point me to the 
>> discussion? I like to understand the choices for the tools I use.
> 
> What problem are you trying to solve here?  Are you annoyed at having to 
> write super.init() and/or initialize your instance variables instead of 
> having the compiler "do the right thing" automatically, or are you worried 
> that calling super.init() will be a small but unnecessary expense at runtime? 
>  Because these seem like completely different problems that should be 
> addressed in completely different ways.
> 
> John.
> 
>> 
>> 
>> P.S. Please excuse any grammatical errors... English is not my first 
>> language.
>> 
>> Thank you for your time and have a great day,
>> Petrescu Victor
>> ___
>> 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] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 1:16 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> I think whether enumerated() is justified as a method on Sequence is one 
> example of a wider question which definitely needs some discussion, which is: 
> where should the standard library draw the line in providing convenience 
> functions that can easily be composed from other functions in the std lib? 
> Here’s another example: 
> 
> SE-100 
> 
>  is a proposal to add an init to Dictionary from a sequence of key/value 
> pairs. It’s a commonly requested feature, and IMO much needed and should be 
> added as soon as we move to the appropriate phase in Swift’s evolution. 
> 
> Another commonly requested Dictionary feature is similar: add a 
> Dictionary.init that takes a sequence, and a closure that maps that sequence 
> to keys. This is useful, for example, when you have a sequence of objects 
> that you frequently need to index into via one property on those objects, so 
> you want to build a fast lookup cache using that property.
> 
> Now, if we implement SE-100, that second request can be easily composed. It 
> would be something like Dictionary(sequence.lazy.map { (key: $0.someProperty, 
> value: $0) } )
> 
> Some people look at that line of code and think sure, that’s what I’d do and 
> it’s easy enough that the second helper shouldn’t be added as it’s 
> superfluous. Others look at it and say that it is unreadable clever-code FP 
> nonsense, and we should just add the helper method because most programmers 
> wouldn’t be able to read or write that easily.
> 
> As we expand (and maybe contract :) the standard library, this kind of 
> question comes up a lot, so it is worth setting out some criteria for judging 
> these
> “helper” methods. Here’s my take on such a list (warning: objectivity and 
> subjectivity blended together in the below).

This is a great analysis and list of criteria.  Thanks for putting this 
together Ben!

> 
> 1. Is it truly a frequent operation?
> 
> The operation needs to carry its weight. Even once we have ABI stability, so 
> the size of the std lib becomes less of a concern as it could ship as part of 
> the OS, we still need to keep helper method growth under control. APIs 
> bristling with methods like an over-decorated Xmas tree are bad for 
> usability. As mentioned in the String manifesto, String+Foundation currently 
> has over 200 methods/properties. Helpers are no good if you can’t find them 
> to use them.
> 
> Someone mentioned that they actually don’t find themselves using enumerated() 
> all that often. I suspect enumerated in its current form isn’t all that 
> useful. In a quick (and non-scientific) review of search results for its use 
> on GitHub, nearly all the examples I see of it are either 1) misuse – see 
> more below, or 2) use of it to perform the equivalent of in-place map where 
> the index is used to subscript into the array and replace it with a 
> transformed element.
> 
> I think the std lib needs an in-place map, and if enumerated() is removed, 
> this one most-common use case should be added at the same time.

I just did a quick search in a couple of projects and found a handful of good 
examples of valid uses of `enumerated`.  I have simplified the examples from 
real world code, but I think they demonstrate the kinds of things this is good 
for.

// only show the first 5 views
for (i, view) in views.enumerated() {
view.hidden = i >= 5
}

// apply alternating view background colors
for (i, view) in views.enumerated() {
view.backgroundColor = i % 2 ? bgColor1 : bgColor2
}

// linear layout
for (i, view) in views.enumerated() {
   let x = width * CGFloat(i)
   view.frame = CGRect(x: x, y: 0, width: width, height: height)
}

// deriving locations for an equally spaced gradient
let locations = colors.enumerated.map { CGFloat($0.0) / CGFloat(colors.count - 
1) }

There are other ways to accomplish similar things (use `prefix` and `dropFirst` 
comes to mind), but many reasonable people would argue that using `enumerated` 
is a very straightforward way to do a lot of things.

> 
> 2. Is the helper more readable? Is the composed equivalent obvious at a 
> glance?
> 
> When an operation is very common, the big win with a helper method is it 
> creates a readable vocabulary. If enumerated() is very common, and everyone 
> sees it everywhere, it makes that code easier to read at a glance.
> 
> That said, I think that the alternative – zip(0…, sequence) – is just as 
> readable once you are familiar with zip and ranges, two concepts that, IMO at 
> least, it is important that every Swift programmer learn about early on. I 
> would even go so far as to say that enumerated is harmful if it discourages 
> new users from discovering zip.

This is a very good point.  Requiring programmers to zip with a range could 
help them 

Re: [swift-evolution] Initializers

2017-01-31 Thread Victor Petrescu via swift-evolution
@John McCall The expense at runtime issue of course. The fact that I need
to add one more line would never bother me enough to bother a few hundreds
ppl in turn :).

On Tue, Jan 31, 2017 at 9:51 PM, John McCall  wrote:

> On Jan 28, 2017, at 1:07 PM, Victor Petrescu via swift-evolution <
> swift-evolution@swift.org> wrote:
> Hello,
>
> My name is Victor, been a developer (C, delphi, php, java, js) for the
> last 10 years or so and lately I had the chance to try swift. I have a
> suggestion/question regarding initializers.
>
> Sidenote: If this is not the correct mailing list for this can you please
> redirect me to the right place?
>
> Consider the following 2 classes and code:
>
> class A {
>  var x:Int
>
>  init() {
>  x = 1
>  }
> }
>
> class B : A {
> override init() {
>  super.init() // Swift FORCES this call
>  x = 2
> }
> }
>
> var a:B
> for i in 0... {
> a = B()  // Whatever... some code that inits B.
> }
>
> This results in  x = 1 then  x = 2... the x = 1 being
> totally useless in this particular case.
>
> In this case, if you don't make the super init you get a compile error.
>
>
>
> *Now... I see the use of this. It ensure that all members are initialized.
> For example if A had a private variable (another strange choice here with
> what private means in swift but I haven't thought on it yet so... maybe is
> a cool choice), the B init could not initialize it. I also understand that
> the cases when you need this minor performance gain are rather rare (but
> they do still exist). So I guess the choice for the super.init() had that
> reasoning.*
>
> Still... my suggestion would be to give a warning, maybe force a key word
> before the init (like iKnowWhatImDoing init() {}), THEN in case vars are
> still not inited give a runtime error (afaik Objective C for example gives
> a warning). That ensures everything is ok and also allows programmers that
> have strange cases to treat them accordingly.
>
> Anyway... that would be my suggestion. Maybe this was discussed before
> also... If this was discussed before can you please point me to the
> discussion? I like to understand the choices for the tools I use.
>
>
> What problem are you trying to solve here?  Are you annoyed at having to
> write super.init() and/or initialize your instance variables instead of
> having the compiler "do the right thing" automatically, or are you worried
> that calling super.init() will be a small but unnecessary expense at
> runtime?  Because these seem like completely different problems that should
> be addressed in completely different ways.
>
> John.
>
>
>
> P.S. Please excuse any grammatical errors... English is not my first
> language.
>
> Thank you for your time and have a great day,
> Petrescu Victor
> ___
> 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] Initializers

2017-01-31 Thread John McCall via swift-evolution
> On Jan 28, 2017, at 1:07 PM, Victor Petrescu via swift-evolution 
>  wrote:
> Hello,
> 
> My name is Victor, been a developer (C, delphi, php, java, js) for the last 
> 10 years or so and lately I had the chance to try swift. I have a 
> suggestion/question regarding initializers.
> 
> Sidenote: If this is not the correct mailing list for this can you please 
> redirect me to the right place?
> 
> Consider the following 2 classes and code:
> 
> class A {
>  var x:Int
> 
>  init() {
>  x = 1
>  }
> }
> 
> class B : A {
> override init() {
>  super.init() // Swift FORCES this call
>  x = 2
> }
> }
> 
> var a:B
> for i in 0... {
> a = B()  // Whatever... some code that inits B.
> }
> 
> This results in  x = 1 then  x = 2... the x = 1 being totally 
> useless in this particular case.
> 
> In this case, if you don't make the super init you get a compile error.
> 
> Now... I see the use of this. It ensure that all members are initialized. For 
> example if A had a private variable (another strange choice here with what 
> private means in swift but I haven't thought on it yet so... maybe is a cool 
> choice), the B init could not initialize it. I also understand that the cases 
> when you need this minor performance gain are rather rare (but they do still 
> exist). So I guess the choice for the super.init() had that reasoning.
> 
> Still... my suggestion would be to give a warning, maybe force a key word 
> before the init (like iKnowWhatImDoing init() {}), THEN in case vars are 
> still not inited give a runtime error (afaik Objective C for example gives a 
> warning). That ensures everything is ok and also allows programmers that have 
> strange cases to treat them accordingly.
> 
> Anyway... that would be my suggestion. Maybe this was discussed before 
> also... If this was discussed before can you please point me to the 
> discussion? I like to understand the choices for the tools I use.

What problem are you trying to solve here?  Are you annoyed at having to write 
super.init() and/or initialize your instance variables instead of having the 
compiler "do the right thing" automatically, or are you worried that calling 
super.init() will be a small but unnecessary expense at runtime?  Because these 
seem like completely different problems that should be addressed in completely 
different ways.

John.

> 
> 
> P.S. Please excuse any grammatical errors... English is not my first language.
> 
> Thank you for your time and have a great day,
> Petrescu Victor
> ___
> 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] Strings in Swift 4

2017-01-31 Thread Jaden Geller via swift-evolution

> On Jan 31, 2017, at 11:26 AM, Dave Abrahams  wrote:
> 
> 
> on Mon Jan 30 2017, Jaden Geller  wrote:
> 
>>> On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> Why should that be out-of-bounds?  Whether it is out-of-bounds would
>>> depend on what items is.  If it's an array, that should be equivalent to
>>> 
>>>  let x = items[items.startIndex..> 
>> It seems to me that `items[0…]` would be equivalent to
>> `items[0…Int.max]` if we’re going to treat `0…` as an “infinite"
>> range, no? Otherwise, we’re either giving subscript of InfiniteRange
>> types special behavior or we’re making subscript ignore past-the-end
>> indices; `”hello”.characters[0…10]` would need to return the same as
>> “hello”.characters[0…4]` to be consistent.
> 
> What is it they say about “a foolish consistency?” ;-)
> 
> More seriously, I think you may be viewing these ranges the wrong way
> around.
> 
>0...
> 
> is not a range with an upper bound of infinity (which is, after all, not
> a number!); it's a range with *no* upper bound.  When you use the range
> for slicing, the collection substitutes its own upper bound.
> 
> HTH,
> 
> -- 
> -Dave

I think that is perfectly reasonable, but then it seems weird to be able to 
iterate over it (with no upper bound) independently of a collection). It would 
surprise me if
```
for x in arr[arr.startIndex…] { print(x) }
```
yielded different results than
```
for i in arr.startIndex… { print(arr[i]) } // CRASH
```
which it does under this model.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Dave Abrahams via swift-evolution

on Mon Jan 30 2017, Jaden Geller  wrote:

>> On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> Why should that be out-of-bounds?  Whether it is out-of-bounds would
>> depend on what items is.  If it's an array, that should be equivalent to
>> 
>>   let x = items[items.startIndex..
> It seems to me that `items[0…]` would be equivalent to
> `items[0…Int.max]` if we’re going to treat `0…` as an “infinite"
> range, no? Otherwise, we’re either giving subscript of InfiniteRange
> types special behavior or we’re making subscript ignore past-the-end
> indices; `”hello”.characters[0…10]` would need to return the same as
> “hello”.characters[0…4]` to be consistent.

What is it they say about “a foolish consistency?” ;-)

More seriously, I think you may be viewing these ranges the wrong way
around.

0...

is not a range with an upper bound of infinity (which is, after all, not
a number!); it's a range with *no* upper bound.  When you use the range
for slicing, the collection substitutes its own upper bound.

HTH,

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ben Cohen via swift-evolution
I think whether enumerated() is justified as a method on Sequence is one 
example of a wider question which definitely needs some discussion, which is: 
where should the standard library draw the line in providing convenience 
functions that can easily be composed from other functions in the std lib? 
Here’s another example: 

SE-100 

 is a proposal to add an init to Dictionary from a sequence of key/value pairs. 
It’s a commonly requested feature, and IMO much needed and should be added as 
soon as we move to the appropriate phase in Swift’s evolution. 

Another commonly requested Dictionary feature is similar: add a Dictionary.init 
that takes a sequence, and a closure that maps that sequence to keys. This is 
useful, for example, when you have a sequence of objects that you frequently 
need to index into via one property on those objects, so you want to build a 
fast lookup cache using that property.

Now, if we implement SE-100, that second request can be easily composed. It 
would be something like Dictionary(sequence.lazy.map { (key: $0.someProperty, 
value: $0) } )

Some people look at that line of code and think sure, that’s what I’d do and 
it’s easy enough that the second helper shouldn’t be added as it’s superfluous. 
Others look at it and say that it is unreadable clever-code FP nonsense, and we 
should just add the helper method because most programmers wouldn’t be able to 
read or write that easily.

As we expand (and maybe contract :) the standard library, this kind of question 
comes up a lot, so it is worth setting out some criteria for judging these 
“helper” methods. Here’s my take on such a list (warning: objectivity and 
subjectivity blended together in the below).

1. Is it truly a frequent operation?

The operation needs to carry its weight. Even once we have ABI stability, so 
the size of the std lib becomes less of a concern as it could ship as part of 
the OS, we still need to keep helper method growth under control. APIs 
bristling with methods like an over-decorated Xmas tree are bad for usability. 
As mentioned in the String manifesto, String+Foundation currently has over 200 
methods/properties. Helpers are no good if you can’t find them to use them.

Someone mentioned that they actually don’t find themselves using enumerated() 
all that often. I suspect enumerated in its current form isn’t all that useful. 
In a quick (and non-scientific) review of search results for its use on GitHub, 
nearly all the examples I see of it are either 1) misuse – see more below, or 
2) use of it to perform the equivalent of in-place map where the index is used 
to subscript into the array and replace it with a transformed element.

I think the std lib needs an in-place map, and if enumerated() is removed, this 
one most-common use case should be added at the same time.

2. Is the helper more readable? Is the composed equivalent obvious at a glance?

When an operation is very common, the big win with a helper method is it 
creates a readable vocabulary. If enumerated() is very common, and everyone 
sees it everywhere, it makes that code easier to read at a glance.

That said, I think that the alternative – zip(0…, sequence) – is just as 
readable once you are familiar with zip and ranges, two concepts that, IMO at 
least, it is important that every Swift programmer learn about early on. I 
would even go so far as to say that enumerated is harmful if it discourages new 
users from discovering zip.

OTOH, an example that I think is strongly justified on readability grounds is 
Sequence.all(match:), a function that checks that every element in a sequence 
matches a predicate. This is by far the most common extension for Sequence on 
GitHub. Yes, you can write this as !seq.contains(!predicate) but that far less 
readable – especially since it requires you write it with a closure that !’s 
the predicate i.e. !seq.contains { !predicate($0) }, because we don’t have a ! 
for composing with predicate functions (though maybe we should).

3. Does the helper have the flexibility to cover all common cases?

This, I think, is where enumerated() really starts to fall down.

Sometimes you want to start from not-zero, so maybe it should be 
Sequence.enumerated(startingFrom: Int = 0)
Sometimes you want non-integer indices so maybe we should add indexed().
Sometimes you want it the other way around (not for a for loop but for passing 
the elements directly into a mapping function) so now you need a flip.
Sometimes you want to enumeration to run backwards in some way.

Less of a problem if you’re already accustomed to composing your enumeration:

Enumerate starting from 1: zip(1…, c)
Enumerate indices: zip(c.indices, c)
Need the pair to be the other way around: zip(c, 0…)
Need the enumeration to run the other way: zip((0..

Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Dave Abrahams via swift-evolution

on Mon Jan 30 2017, Olivier Tardieu  wrote:

> Thanks for the clarifications.
> More comments below.
>
> dabrah...@apple.com wrote on 01/24/2017 05:50:59 PM:
>
>> Maybe it wasn't clear from the document, but the intention is that
>> String would be able to use any model of Unicode as a backing store, and
>> that you could easily build unsafe models of Unicode... but also that
>> you could use your unsafe model of Unicode directly, in string-ish ways.
>
> I see. If I understand correctly, it will be possible for instance to 
> implement an unsafe model of Unicode with a UInt8 code unit and a 
> maxLengthOfEncodedScalar equal to 1 by only keeping the 8 lowest bits of 
> Unicode scalars.

Eh... I think you'd just use an unsafe Latin-1 for that; why waste a
bit?

Here's an example (work very much in-progress):
https://github.com/apple/swift/blob/9defe9ded43c6f480f82a28d866ec73d803688db/test/Prototypes/Unicode.swift#L877


>> > A lot of machine processing of strings continues to deal with 8-bit
>> > quantities (even 7-bit quantities, not UTF-8).  Swift strings are
>> > not very good at that. I see progress in the manifesto but nothing
>> > to really close the performance gap with C.  That's where "unsafe"
>> > mechanisms could come into play.
>> 
>> extendedASCII is supposed to address that.  Given a smart enough
>> optimizer, it should be possible to become competitive with C even
>> without using unsafe constructs.  However, we recognize the importance
>> of being able to squeeze out that last bit of performance by dropping
>> down to unsafe storage.
>
> I doubt a 32-bit encoding can bridge the performance gap with C in
> particular because wire protocols will continue to favor compact
> encodings.  Incoming strings will have to be expanded to the
> extendedASCII representation before processing and probably compacted
> afterwards. So while this may address the needs of computationally
> intensive string processing tasks, this does not help simple parsing
> tasks on simple strings.

I'm pretty sure it does; we're not going to change representations

extendedASCII doesn't require anything to actually be expanded to
32-bits per code unit, except *maybe* in a register, and then only if
the optimizer isn't smart enough to eliminate zero-extension followed by
comparison with a known narrow value.  You can always

  latin1.lazy.map { UInt32($0) }

to produce 32-bit code units.  All the common encodings are ASCII
supersets, so this will “just work” for those.  The only places where it
becomes more complicated is in encodings like Shift-JIS (which might not
even be important enough to support as a String backing-storage format).

>
>> > To guarantee Unicode correctness, a C string must be validated or 
>> > transformed to be considered a Swift string.
>> 
>> Not really.  You can do error-correction on the fly.  However, I think
>> pre-validation is often worthwhile because once you know something is
>> valid it's much cheaper to decode correctly (especially for UTF-8).
>
> Sure. Eager vs. lazy validation is a valuable distinction, but what I am 
> after here is side-stepping validation altogether. I understand now that 
> user-defined encodings will make side-stepping validation possible.

Right.

>
>> > If I understand the C String interop section correctly, in Swift 4,
>> > this should not force a copy, but traversing the string is still
>> > required. 
>> 
>> *What* should not force a copy?
>
> I would like to have a constructor that takes a pointer to a 
> null-terminated sequence of bytes (or a sequence of bytes and a length) 
> and turns it into a Swift string without allocation of a new backing store 
> for the string and without copying the bytes in the sequence from one 
> place in memory to another. 

We probably won't expose this at the top level of String, but you should
be able to construct an UnsafeCString (which is-a Unicode) and then, if
you really need the String type, construct a String from that:

   String(UnsafeCString(ntbs))

That would not do any copying.

> I understand this may require the programmer to handle memory
> management for the backing store.
>
>> > I hope I am correct about the no-copy thing, and I would also like to
>> > permit promoting C strings to Swift strings without validation.  This
>> > is obviously unsafe in general, but I know my strings... and I care
>> > about performance. ;)
>> 
>> We intend to support that use-case.  That's part of the reason for the
>> ValidUTF8 and ValidUTF16 encodings you see here:
>> https://github.com/apple/swift/blob/unicode-rethink/stdlib/public/
>> core/Unicode2.swift#L598
>> and here:
>> https://github.com/apple/swift/blob/unicode-rethink/stdlib/public/
>> core/Unicode2.swift#L862
>
> OK
>
>> > More importantly, it is not possible to mutate bytes in a Swift string
>> > at will.  Again it makes sense from the point of view of always
>> > correct Unicode sequences.  But it does not for machine processing of
>> > C strings with C-like 

Re: [swift-evolution] [Proposal] Add Array binary search to the standard library

2017-01-31 Thread Dave Abrahams via swift-evolution

on Mon Jan 30 2017, Alexey Komnin  wrote:

> Hello to everyone.
>
> Let me put my two cents.
>
>>> I didn’t want the SortedArray to conform to MutableCollection or
>>> even RandomAccessCollection as I felt it was not needed just to
>>> support binary search and prevent re-sorting.
>>
>> You are right not to support MutableCollection or
>> RangeReplaceableCollection, as those would allow you to violate the
>> “sorted” invariant.  However, it should conform to
>> RandomAccessCollection; that's really easy to implement and would
>> improve ease-of-use a lot.
>
> Are we able to add some kind of type constraint which allows
> append/prepend operations on a particular collection? Seems like a
> good replacement for MutableCollection in this case. It should be
> available to append elements greater or equal to the last element in
> SortedArray, isn't it?

I think we should handle that with a method like this

  /// Inserts `x` in the correct position, using `positionHint`
  /// to improve performance if it is accurate.
  func insert(_ x: Element, positionHint: Index) -> Index

>
>
> Regards,
> Alex Komnin.
>
> On Mon, Jan 30, 2017 at 3:21 AM, Dave Abrahams via swift-evolution
>  wrote:
>>
>> Hi Cihat,
>>
>> Thanks for diving in here!  For reference, here's the last thing I said
>> about this topic (IIRC):
>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016729.html
>>
>> Also
>> https://github.com/apple/swift/blob/master/test/Prototypes/Algorithms.swift.gyb#L679
>>
>> Note: the comment there isn't quite right: 
>> 
>>
>> on Sun Jan 29 2017, Cihat Gündüz  wrote:
>>
>>> Hi guys, I know this topic is probably out of scope for Swift 4
>>> and a proposal was already rejected for Swift 3, but I’d like to share
>>> my two cents on this as I just wrote a SortedArray class with support
>>> for binary search in my open source library HandySwift.
>>>
>>> You can see my classes current implementation here:
>>> https://github.com/Flinesoft/HandySwift/blob/cd7ae7041c8174cd655f24eae653f76697875a48/Sources/Structs/SortedArray.swift
>>>
>>> My goal was to provide only what is commonly needed when working with
>>> big arrays in algorithms. For me this included:
>>>
>>> - having a type that keeps a sorted array to prevent re-sorting (solution: 
>>> the SortedArray class)
>>
>> Sounds consistent with my feedback... but it doesn't conform to
>> RandomAccessCollection.  Why not?
>>
>>> - have a method that can find an object using binary search (solution: the 
>>> index method)
>>
>> Please see the algorithms prototype
>>
>>> - allow partitioning the array into smaller parts (solution: subscript, 
>>> prefix & suffix methods)
>>
>> * The collection returned by the slicing subscript should obey the law
>>
>>  a[i..>
>>   Normally that means you want to make it a different type from a.
>>
>>> - prevent re-implementing the Array class (solution: a getter to the
>>>   stored internal array)
>>
>> Not sure I understand what this is supposed to mean.
>>
>>> Also note that the SortedArray in my approach allows all types that
>>> conform to `Sequence` as input with `Comparable` elements and saves
>>> them into a sorted array on initialization. That array is also
>>> publicly read-accessible. Inserting and deleting objects from the
>>> SortedArray are possible, too, but that’s just few of the
>>> MutableCollection methods.
>>
>> Actually no, those are RangeReplaceableCollection methods.
>>
>>> I didn’t want the SortedArray to conform to MutableCollection or
>>> even RandomAccessCollection as I felt it was not needed just to
>>> support binary search and prevent re-sorting.
>>
>> You are right not to support MutableCollection or
>> RangeReplaceableCollection, as those would allow you to violate the
>> “sorted” invariant.  However, it should conform to
>> RandomAccessCollection; that's really easy to implement and would
>> improve ease-of-use a lot.
>>
>>
>>> Maybe my approach can somehow help forming the final solution to be
>>> included into Swift once this features is tackled again.
>>>
>>> Best regards,
>>> Cihat
>>> ___
>>> 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

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


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Dave Abrahams via swift-evolution

on Mon Jan 30 2017, Brent Royal-Gordon  wrote:

>> On Jan 30, 2017, at 11:25 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>>> I mean that `OptionSet.RawValue` currently has to conform to
>>> `BitwiseOperations`, 
>> 
>> Actually it doesn't.  You just have to implement these yourself in that
>> case:
>> 
>>  extension OptionSet where Self.RawValue : BitwiseOperations {
>
> Oh, I didn't realize it was implemented that way (and was going to stay that 
> way). Thanks for the
> correction.
>
>>> but would now need to conform to `BinaryInteger` (or a sub-protocol).
>> 
>> Does that limit you in some useful way?
>
> Well, a type like `Data` could be usefully conformed to
> `BitwiseOperations`, which would permit its use as a variable-sized
> bit buffer, but conforming it to `BinaryInteger` would make no sense
> and might cause mis-conformances. (For instance,
> `BinaryInteger.Type.+` and the `+` operator that works on
> `RangeReplaceableCollection`s like `Data` are incompatible). You would
> instead have to use a big-int type, but it's apparently common for
> those to be implemented in ways that make bitwise operations slow.

What's wrong with having Data (or most likely, a trivial wrapper over
Data) conform to SetAlgebra with Int elements?  You get the same
functionality.

> However, unless I'm mistaken, I believe a `BitwiseOperations` protocol
> could be extracted from `BinaryInteger` later (right? Resilience
> permits you to add a new super-protocol and move some of the
> sub-protocol's requirements up into it?), so we can pick that up
> later.

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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Jacob Bandes-Storch via swift-evolution
I'm still a fan of that indexed() proposal...
On Tue, Jan 31, 2017 at 8:52 AM Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 31, 2017, at 10:46 AM, Chris Eidhof  wrote:
>
> I agree that it's very useful. I use it regularly. The documentation isn't
> that unclear, imo. To me, the underlying problem isn't enumerated. I think
> the underlying cause is that collections aren't indexed with zero based
> indices.if you don't understand this (which is the case for many
> experienced programmers new to Swift) it's hard to understand, and (too)
> easy to make a mistake.
>
>
> This indicates that the underlying problem is *not* enumerated at all.
> The underlying problem is that Swift is still a relatively new language and
> it does some things differently than other languages (for very good
> reasons).
>
> You’re making a great case for the need to continue spreading knowledge
> about Swift’s collection model through the community.
>
> I don’t think it’s problematic for an experienced programmer who is new to
> the language to bump up against this when the reach for `enumerated`.
> They’re going to need to learn the collection model sooner or later.
>
>
> On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I totally sympathize with users being confused. It's an interesting idea
> to move it to Array only.
>
> The thing is, it does make sense (and wouldn't be confusing) to enumerate
> a dictionary or set. Moreover, the behavior is _exactly_ what it says on
> the tin: when you enumerate something in real life, there is no sense in
> which the number is related to some sort of index. Can we fix this by
> documentation? Like, a big blaring "don't use this when you want the index”?
>
>
> +1.  A similar method on collection that provides indices might be useful
> but that doesn’t mean we should remove `enumerated`.  User confusion should
> be addressed by documentation.
>
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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
>
> --
> Sent from my phone
>
> ___
> 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] [Draft] Test-Only Package Dependencies and Targets

2017-01-31 Thread Rick Ballard via swift-evolution
+ swift-build-dev

To take a step back here, there are two problems I see in this space:

1) Building unnecessary test-only stuff.

Say you have a package A which depends on a package B. B might declare a 
library, a test module, and some auxiliary target that's only needed by the 
tests. Today, if you check out A and run `swift build`, it will build B's 
auxiliary target (among other things built). That's unnecessary, and it would 
be nice to avoid that.

The product definitions proposal will fix this. Once that's implemented, B 
would publish its library as its only product, and A would declare that it 
depends on that product. Then, when building A, we would know that we don't 
need the auxiliary target from B, and wouldn't build it. So I think the 
products proposal will solve this problem.

2) Cloning unnecessary test-only stuff.

Say you have a package A which depends on a package B, and B has a test module 
which depends on a package C. Once the products proposal has been implemented 
and you adopt it, running `swift build` on A will be smart enough not to build 
the test module from B or any of the targets from C; however, SwiftPM will 
still clone the C repository when doing dependency resolution, even though it 
never winds up building its products.

I don't personally see that as a major problem, but it is one that would be 
nice to address at some point. Ways we could address this include:

– We could add a "testDependencies" property on the package. These dependencies 
would only be resolved and cloned in situations where one or more test targets 
from that package need to be built. Some problems with this would be:

* Since these dependencies would only conditionally resolve, but 
otherwise would affect dependency resolution as normal, this could lead to some 
really unexpected emergent behavior. For example, if a package that's only 
included in the graph via testDependencies happens to depend on another package 
that's otherwise already in the graph, but with a more restrictive version 
specification, then whether or not you're building tests would force that other 
package to re-resolve with a different version.

* This is a non-generalized solution to a general problem. That is, 
once we have the products proposal implemented, you could wind up in this 
situation with no tests involved, but this mechanism wouldn't solve the problem 
in that case. To give a concrete example, if A depends on B, B vends two 
products, and only one of them depends on C, it's unnecessary to clone C unless 
the product that needs it is used by A. A properly general mechanism would let 
you make that dependency conditional on whether you need it for whatever 
reason, and not tie it to testing in particular. Another reason you might have 
this problem is if you have a dependency that only applies on one platform 
(e.g. linux but not macOS). (Conditional compilation blocks can be used for the 
platform case, but – once we have a better mechanism – I don't think that they 
should be used, for reasons that would be best discussed in its own thread).

* Adding additional properties to the Package should be done carefully. 
Every new property is new API surface area, and makes our documentation, 
initializer, etc more complicated. In my opinion, this new property doesn't 
justify that cost if it's just saving you from initial cloning of the extra 
packages.

– We could add in-line dependencies for targets, as Ankit suggested. This is a 
more generalizable mechanism than "testDependencies". That said, it could 
potentially require you to duplicate your dependency declaration, which is bad. 
(E.g. if two test targets in your package depend on the same auxiliary package, 
that dependency would need to be stated twice). It also adds unfortunate 
complexity.

– We could add a general mechanism for declaring dependencies as conditional, 
supporting a variety of possible conditions. Some of the SwiftPM developers are 
in the early discussion stages for a proposal for how to to make various parts 
of a manifest conditional, as part of a larger conversation on build settings; 
we'll bring our thoughts to this list once we have something coherent to 
propose. But if we come up with a general syntax for making things like 
settings conditional, the same consistent syntax could potentially be applied 
to dependencies as well.

- - -

Personally, I think that the products proposal solves the first problem nicely, 
and that we should revisit the second problem as part of an upcoming 
conversation about conditionals in the manifest.

- Rick

> On Jan 30, 2017, at 11:55 AM, Robert Widmann via swift-evolution 
>  wrote:
> 
> 
>> On Jan 30, 2017, at 2:38 PM, Ankit Agarwal > > wrote:
>> 
>> 
>> Not in practice (with respect to package manifests). In fact, it seems that, 
>> given there are separate commands (swift build and swift test), 

Re: [swift-evolution] [Review] SE-0150 Package Manager Support for branches

2017-01-31 Thread Rick Ballard via swift-evolution

> On Jan 30, 2017, at 11:43 PM, Martin Waitz  wrote:
> 
> Hi Boris,
> 
>> Am 31.01.2017 um 03:48 schrieb Rick Ballard > >:
>> 
>>> 
>>> On Jan 25, 2017, at 11:06 PM, Martin Waitz via swift-evolution 
>>> > wrote:
>>> 
>>> OK, you are right, branches can be helpful to have in the manifest.
>>> But I’m still confident that we must not put explicit version information 
>>> into it.
>>> They belongs into the `Package.pins` file.
>>> That is enough to get reproducible builds.
>> 
>> By "explicit version information", do you mean that you shouldn't put a git 
>> revision hash in the manifest – only branches and version tags should be 
>> acceptable?
> 
> yes exactly.
> BTW: the more I think about it, the more I like the possibility to specify a 
> branch in the manifest.
> 
>> I'd agree that the revision-based initializer is a marginal feature; 
>> normally your package should depend on a version range or is tracking a 
>> branch. That said, we can imagine that you might wind up needing to peg your 
>> dependency to a specific revision that isn't a version tag, and not track a 
>> moving branch, so this seemed like a fairly harmless feature to add for that 
>> case. What is your objection about supporting that?
>> 
>> The decision about whether to put this information in your pins or in your 
>> manifest should be driven by whether it's something your package requires, 
>> or is just a workflow choice. If you just want to temporarily stick to a 
>> specific revision of your dependency for workflow reasons, pinning is the 
>> right way to do that. If, however, your package currently requires that 
>> revision, and isn't going to work properly without it, then the manifest is 
>> the right way to express that. You'd want that specification to stick even 
>> if someone did `swift package update --repin` to get newer pinned revisions.
> 
> Well, I guess your package will also work with all commits following your 
> special one.
> Then I’d be enough to specify the branch: your special dependency version is 
> already specified in the pins file and `swift package update` will only 
> update to newer revisions.
> 
> So why would you (temporarily) want to stick to a specific version?
> Because it happens to be the only compatible one at that time.
> So even that is a workflow thing and not a „this is the one and only“.
> And if you really really need to choose a specific commit which is in the 
> past, then you can always create a special branch just for it.
> 
> I really like to have a clear separation between manifest and the pins file.
> Otherwise I fear that inexperienced maintainers hard-code their dependencies 
> to a specific version by accident.
> I've seen too strict version specifications too often already (e.g. on npm) 
> ;-)

This is not for the case where a package will work with all commits on a branch 
after the designated one. If that's the case, indeed a branch should be 
specified instead. This is for the case where there is a specific commit that's 
needed, and it doesn't have a version tag, and it either isn't on a current 
branch or the branch has moved past it to something incompatible.

You can't necessarily create a special branch for such a commit because you may 
not have permissions to push new branches to the repositories of your 
dependencies.

One thing to note is that if a maintainer does use this feature 
inappropriately, their package will fail once they tag it for release. One of 
the behaviors specified by this proposal is that if a package is found via a 
version tag, then if that package specifies any further dependencies via branch 
or revision, that is an error. The rule is that any versioned tag needs to 
fully specify all other dependencies via versioned tags. So a novice user will 
find out pretty quickly that they can't rely on revision specifiers for their 
actual releases.

In the future we hope to add a command to SwiftPM to help you prepare your 
package for a tagged release. That process would check this for you, among 
other things, so you'd find out about this problem before you created the tag.

- Rick

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


Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread Daniel Duan via swift-evolution
> 
> On Jan 31, 2017, at 8:47 AM, Alex Hoppen  wrote:
> 
> Amendment to the history of the bug after I had a look at the bug reports 
> again: SR-1895 explicitly asked that 
> 
> let s: String? = "hi"
> s.map {print($0)}

This is the anti-pattern we try to discourage. FYI.

> should not produce any warnings while it did so during beta 1. 
> 
> – Alex
> 
>> On 31 Jan 2017, at 09:07, Alex Hoppen via swift-evolution 
>>  wrote:
>> 
>> This was a deliberate change between Swift 3 beta 1 and beta 2 after a 
>> friend of mine pointed the following inconsistency out to me:
>> 
>> struct Foo {
>>  func bar() {}
>> }
>> let foo: Foo? = Foo()
>> foo?.bar() // Does not create a warning
>> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
>> 
>> After some offline discussion at WWDC with the Swift team we decided to move 
>> to a consistent model where ()?, ()??, … is always discardable since we 
>> didn't want to take the convenience of foo?.bar() away (something that 
>> regularly occurs with weak variables, e.g. captures in closures).
>> 
>> So much for the history of this feature.
>> 
>> – Alex
>> 
>> 
>>> On 30 Jan 2017, at 22:58, Daniel Duan via swift-evolution 
>>>  wrote:
>>> 
>>> Hi all,
>>> 
>>> Right now, expressions that evaluates to Optional<()>, 
>>> Optional>… gets special treatment when it’s unused. For 
>>> example:
>>> 
>>> func f(s: String) {}
>>> let s: String = “”
>>> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
>>> and unused.
>>> 
>>> func g() throws {}
>>> try? g() // no warnings here neither.
>>> 
>>> This is convenient, but encourages composing map/filter/reduce, etc with 
>>> side-effect-ful functions, which we have found a few cases of in our 
>>> production code recently. Granted, these cases could’ve been caught with 
>>> more careful code reviews. But we wouldn’t have missed them if this 
>>> “feature” didn’t exist.
>>> 
>>> I think we should remove the special treatment so that code in the example 
>>> above would generate a warning about `()?` being unused. Users can silence 
>>> it manually by assigning the result to `_`. 
>>> 
>>> OTOH, this would undermine the convenience of `try?` when the throwing 
>>> function don’t return anything.
>>> 
>>> What do y’all think?
>>> 
>>> Daniel Duan
>>> ___
>>> 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] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 10:46 AM, Chris Eidhof  wrote:
> 
> I agree that it's very useful. I use it regularly. The documentation isn't 
> that unclear, imo. To me, the underlying problem isn't enumerated. I think 
> the underlying cause is that collections aren't indexed with zero based 
> indices.if you don't understand this (which is the case for many experienced 
> programmers new to Swift) it's hard to understand, and (too) easy to make a 
> mistake.

This indicates that the underlying problem is *not* enumerated at all.  The 
underlying problem is that Swift is still a relatively new language and it does 
some things differently than other languages (for very good reasons).

You’re making a great case for the need to continue spreading knowledge about 
Swift’s collection model through the community.

I don’t think it’s problematic for an experienced programmer who is new to the 
language to bump up against this when the reach for `enumerated`.  They’re 
going to need to learn the collection model sooner or later.  

> 
> On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution 
> > wrote:
>> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> I totally sympathize with users being confused. It's an interesting idea to 
>> move it to Array only.
>> 
>> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
>> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
>> tin: when you enumerate something in real life, there is no sense in which 
>> the number is related to some sort of index. Can we fix this by 
>> documentation? Like, a big blaring "don't use this when you want the index”?
> 
> +1.  A similar method on collection that provides indices might be useful but 
> that doesn’t mean we should remove `enumerated`.  User confusion should be 
> addressed by documentation.
> 
>> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
>> > wrote:
>> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
>> > Here are three previous discussion about this topic:
>> >
>> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
>> > CollectionType
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
>> >  
>> > 
>> > and
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
>> >  
>> > 
>> >
>> >
>> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
>> >  
>> > 
>> >
>> >
>> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
>> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>> >  
>> > 
>> 
>> To clarify, the discussions I linked to don't all propose to remove or
>> replace `enumerated()`, but they all talk about the potential confusion
>> about what `enumerated()` does and does not do.
>> 
>> ___
>> 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 
> 
> -- 
> Sent from my phone

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


Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread Alex Hoppen via swift-evolution
Amendment to the history of the bug after I had a look at the bug reports 
again: SR-1895  explicitly asked that 

let s: String? = "hi"
s.map {print($0)}

should not produce any warnings while it did so during beta 1. 

– Alex

> On 31 Jan 2017, at 09:07, Alex Hoppen via swift-evolution 
>  wrote:
> 
> This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend 
> of mine pointed the following inconsistency out to me:
> 
> struct Foo {
>  func bar() {}
> }
> let foo: Foo? = Foo()
> foo?.bar() // Does not create a warning
> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
> 
> After some offline discussion at WWDC with the Swift team we decided to move 
> to a consistent model where ()?, ()??, … is always discardable since we 
> didn't want to take the convenience of foo?.bar() away (something that 
> regularly occurs with weak variables, e.g. captures in closures).
> 
> So much for the history of this feature.
> 
> – Alex
> 
> 
>> On 30 Jan 2017, at 22:58, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>> Hi all,
>> 
>> Right now, expressions that evaluates to Optional<()>, 
>> Optional>… gets special treatment when it’s unused. For example:
>> 
>> func f(s: String) {}
>> let s: String = “”
>> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
>> and unused.
>> 
>> func g() throws {}
>> try? g() // no warnings here neither.
>> 
>> This is convenient, but encourages composing map/filter/reduce, etc with 
>> side-effect-ful functions, which we have found a few cases of in our 
>> production code recently. Granted, these cases could’ve been caught with 
>> more careful code reviews. But we wouldn’t have missed them if this 
>> “feature” didn’t exist.
>> 
>> I think we should remove the special treatment so that code in the example 
>> above would generate a warning about `()?` being unused. Users can silence 
>> it manually by assigning the result to `_`. 
>> 
>> OTOH, this would undermine the convenience of `try?` when the throwing 
>> function don’t return anything.
>> 
>> What do y’all think?
>> 
>> Daniel Duan
>> ___
>> 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] Removing enumerated?

2017-01-31 Thread Chris Eidhof via swift-evolution
I agree that it's very useful. I use it regularly. The documentation isn't
that unclear, imo. To me, the underlying problem isn't enumerated. I think
the underlying cause is that collections aren't indexed with zero based
indices.if you don't understand this (which is the case for many
experienced programmers new to Swift) it's hard to understand, and (too)
easy to make a mistake.

On Tue, 31 Jan 2017 at 17:41, Matthew Johnson via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I totally sympathize with users being confused. It's an interesting idea
> to move it to Array only.
>
> The thing is, it does make sense (and wouldn't be confusing) to enumerate
> a dictionary or set. Moreover, the behavior is _exactly_ what it says on
> the tin: when you enumerate something in real life, there is no sense in
> which the number is related to some sort of index. Can we fix this by
> documentation? Like, a big blaring "don't use this when you want the index”?
>
>
> +1.  A similar method on collection that provides indices might be useful
> but that doesn’t mean we should remove `enumerated`.  User confusion should
> be addressed by documentation.
>
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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
>
-- 
Sent from my phone
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Sean Heber via swift-evolution
In practical usage, I rarely use enumerated() - and almost every time I do use 
it, I end up refactoring 20 minutes later to not use it. Maybe that's just me, 
though. I imagine this isn’t helpful feedback. :P But perhaps we (or I) need to 
understand what it’s being used for or if there’s a different way to think 
about it.

l8r
Sean


> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I totally sympathize with users being confused. It's an interesting idea to 
> move it to Array only.
> 
> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
> tin: when you enumerate something in real life, there is no sense in which 
> the number is related to some sort of index. Can we fix this by 
> documentation? Like, a big blaring "don't use this when you want the index"?
> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
>  wrote:
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
> 
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
> 
> ___
> 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] Removing enumerated?

2017-01-31 Thread Xiaodi Wu via swift-evolution
I totally sympathize with users being confused. It's an interesting idea to
move it to Array only.

The thing is, it does make sense (and wouldn't be confusing) to enumerate a
dictionary or set. Moreover, the behavior is _exactly_ what it says on the
tin: when you enumerate something in real life, there is no sense in which
the number is related to some sort of index. Can we fix this by
documentation? Like, a big blaring "don't use this when you want the index"?
On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution <
swift-evolution@swift.org> wrote:

> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> > and
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`
> collections
> >
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
>
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
>
> ___
> 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] Removing enumerated?

2017-01-31 Thread Matthew Johnson via swift-evolution

> On Jan 31, 2017, at 10:36 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I totally sympathize with users being confused. It's an interesting idea to 
> move it to Array only.
> 
> The thing is, it does make sense (and wouldn't be confusing) to enumerate a 
> dictionary or set. Moreover, the behavior is _exactly_ what it says on the 
> tin: when you enumerate something in real life, there is no sense in which 
> the number is related to some sort of index. Can we fix this by 
> documentation? Like, a big blaring "don't use this when you want the index”?

+1.  A similar method on collection that provides indices might be useful but 
that doesn’t mean we should remove `enumerated`.  User confusion should be 
addressed by documentation.

> On Tue, Jan 31, 2017 at 09:35 Ole Begemann via swift-evolution 
> > wrote:
> On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:
> > Here are three previous discussion about this topic:
> >
> > 1) December 2015: [Idea] Add an (Index,Element) sequence to
> > CollectionType
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
> >  
> > 
> > and
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html
> >  
> > 
> >
> >
> > 2) April 2016: [Idea] Replace enumerate() with something more explicit
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html
> >  
> > 
> >
> >
> > 3) September 2016: [Proposal draft] Introducing `indexed()`collections
> > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html
> >  
> > 
> 
> To clarify, the discussions I linked to don't all propose to remove or
> replace `enumerated()`, but they all talk about the potential confusion
> about what `enumerated()` does and does not do.
> 
> ___
> 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] Warn about unused Optional.some(())

2017-01-31 Thread Haravikk via swift-evolution

> On 31 Jan 2017, at 09:07, Alex Hoppen via swift-evolution 
>  wrote:
> 
> This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend 
> of mine pointed the following inconsistency out to me:
> 
> struct Foo {
>  func bar() {}
> }
> let foo: Foo? = Foo()
> foo?.bar() // Does not create a warning
> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
> 
> After some offline discussion at WWDC with the Swift team we decided to move 
> to a consistent model where ()?, ()??, … is always discardable since we 
> didn't want to take the convenience of foo?.bar() away (something that 
> regularly occurs with weak variables, e.g. captures in closures).
> 
> So much for the history of this feature.

Thanks for clarifying, but this is an interesting case actually; it seems the 
problem here is the ternary, as presumably the following would have worked just 
fine:

if true { foo?.bar() }
else { foo?.bar() }

So your example's problem seems to stem then from the fact that the ternary's 
type isn't inheriting the discardable nature of the two branches. I wonder then 
if an alternative solution might to have discardable be an inheritable 
property, while keeping optional chaining implicitly discardable?

For example:

@discardableResult func foo() -> Int { return 1 }
func bar() -> Int { return 2 }
struct Baz { func baz() {}}

let a:Baz? = Baz()
true ? foo() : bar() // type is Int, should produce a warning
true ? foo() : foo() // type is discardable Int, no warning necessary
true ? a?.baz() : a?.baz() // type is discardable Void, no warning necessary

The idea basically being that @discardableResult becomes a property of return 
types that is passed for as long as it is in common, but does not prevent two 
types (one discardable, one not) from being equal.

This might give a best of both? As method chaining producing implicitly 
discardable results would allow your example to behave as expected, but other 
cases can still be configured as desired with @discardableResult (or not).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Stephen Canon via swift-evolution
It’s

(a) the inverse operation of doubleWidthMultiply.
(b) an important building block for fast “small bignum arithmetic” (2-16 ish 
words). If you have this operation, it’s easy to build the divide that does 
DoubleWidth / DoubleWidth.
(c) the widest divide operation that maps reasonably cleanly to common hardware 
when T = Word.

– Steve

> On Jan 31, 2017, at 6:59 AM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
> What, exactly, is the intended purpose of doubleWidthDivide?
> 
> I ask because, outside of degenerate cases, a quotient and remainder will fit 
> in the same size type as the operands.
> 
> So widthX / widthY will have quotient that fits in width X, and remainder 
> that fits in width Y.
> 
> In general, we cannot assume either one would be any smaller than that.
> 
> Nevin
> 
> 
> On Monday, January 30, 2017, Brent Royal-Gordon via swift-evolution 
> > wrote:
> > On Jan 30, 2017, at 11:31 AM, Max Moiseev  > > wrote:
> >
> > doubleWidthDivide should not return a DoubleWidth for two reasons:
> > 1. The components of it’s return type are not high and low, but are 
> > quotient and remainder instead.
> > 2. In DoubleWidth high is T and low is T.Magnitude, which is not the 
> > case for quotient and remainder.
> 
> You're right about the return value; for `doubleWidthDivide(_:_:)`, I was 
> thinking about changing the dividend. Specifically, I'm thinking we should 
> change these to:
> 
> static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) -> 
> DoubleWidth
> static func doubleWidthDivide(_ lhs: DoubleWidth, _ rhs: Self) 
> -> (quotient: Self, remainder: Self)
> 
> I'm also thinking a little bit about spelling of these operations. I'd *love* 
> to be able to call them `*` and `/` and let the type system sort things out, 
> but that would cause problems, especially for multiply (since the return 
> value is the only thing different from a normal `*`). We could invent a new 
> operator, but that would be a bit much. Could these be simply `multiply` and 
> `divide`, and we'll permit the `DoubleWidth` parameter/return type to explain 
> itself?
> 
> I'm also thinking the second parameter should be labeled `by`, since that's 
> the way people talk about these operations. Applying both of these 
> suggestions, we'd get:
> 
> static func multiply(_ lhs: Self, by rhs: Self) -> DoubleWidth
> static func divide(_ lhs: DoubleWidth, by rhs: Self) -> 
> (quotient: Self, remainder: Self)
> 
> let x = Int.multiply(a, by: b)
> let (aʹ, r) = Int.divide(x, by: b)
> assert(a == aʹ)
> assert(r == 0)
> 
> Should the standard library provide extensions automatic definitions of 
> multiplication and division in terms of their double-width equivalents?
> 
> extension FixedWidthInteger {
> func multipliedWithOverflow(by other: Self) -> (partialValue: 
> Self, overflow: ArithmeticOverflow) {
> let doubledResult = Self.multiply(self, by: other)
> let overflowed = doubledResult.high != (doubledResult 
> < 0 ? -1 : 0)
> return (Self(bitPattern: doubledResult.lowerValue), 
> overflowed ? .overflowed : .none)
> }
> 
> func quotientAndRemainder(dividingBy other: Self) -> 
> (quotient: Self, remainder: Self) {
> precondition(other != 0, "Divide by zero")
> return Self.divide(DoubleWidth(self), by: other)
> }
> 
> func dividedWithOverflow(by other: Self) -> (partialValue: 
> Self, overflow: ArithmeticOverflow) {
> guard other != 0 else { return (self, .overflowed) }
> 
> let result = Self.divide(self, by: other)
> return (result.quotient, .none)
> }
> 
> static func * (lhs: Self, rhs: Self) -> Self {
> let result = lhs.dividedWithOverflow(by: rhs)
> precondition(result.overflow == .none, 
> "Multiplication overflowed")
> return result.partialValue
> }
> 
> static func / (lhs: Self, rhs: Self) -> Self {
> let result = lhs.quotientAndRemainder(dividingBy: rhs)
> return result.quotient
> }
> 
> static func % (lhs: Self, rhs: Self) -> Self {
> let result = lhs.quotientAndRemainder(dividingBy: rhs)
> return result.remainder
> }
> }
> 
> Hmm...having actually written this out, I now have a couple of concerns:
> 
> 1. There's a lot of jumping back and forth between instance methods and 
> static methods. Can we standardize on just static methods? Or make sure that 
> the user-facing 

Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread Daniel Duan via swift-evolution
Good to know the history. If I were to fix the inconsistency, I'd add the 
warning to optional chaining instead. 

Deliberately make the compiler give us *less* information for esthetic reasons 
feels wrong to me. As I mentioned in the original email, this has cost us a few 
unnoticed bad patterns slipping into our production. That's the opposite of 
what this type of warning is supposed to achieve.

> On Jan 31, 2017, at 1:07 AM, Alex Hoppen  wrote:
> 
> This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend 
> of mine pointed the following inconsistency out to me:
> 
> struct Foo {
>  func bar() {}
> }
> let foo: Foo? = Foo()
> foo?.bar() // Does not create a warning
> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
> 
> After some offline discussion at WWDC with the Swift team we decided to move 
> to a consistent model where ()?, ()??, … is always discardable since we 
> didn't want to take the convenience of foo?.bar() away (something that 
> regularly occurs with weak variables, e.g. captures in closures).
> 
> So much for the history of this feature.
> 
> – Alex
> 
> 
>> On 30 Jan 2017, at 22:58, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>> Hi all,
>> 
>> Right now, expressions that evaluates to Optional<()>, 
>> Optional>… gets special treatment when it’s unused. For example:
>> 
>> func f(s: String) {}
>> let s: String = “”
>> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
>> and unused.
>> 
>> func g() throws {}
>> try? g() // no warnings here neither.
>> 
>> This is convenient, but encourages composing map/filter/reduce, etc with 
>> side-effect-ful functions, which we have found a few cases of in our 
>> production code recently. Granted, these cases could’ve been caught with 
>> more careful code reviews. But we wouldn’t have missed them if this 
>> “feature” didn’t exist.
>> 
>> I think we should remove the special treatment so that code in the example 
>> above would generate a warning about `()?` being unused. Users can silence 
>> it manually by assigning the result to `_`. 
>> 
>> OTOH, this would undermine the convenience of `try?` when the throwing 
>> function don’t return anything.
>> 
>> What do y’all think?
>> 
>> Daniel Duan
>> ___
>> 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] Removing enumerated?

2017-01-31 Thread Ole Begemann via swift-evolution

On 31/01/2017 16:19, Ole Begemann via swift-evolution wrote:

Here are three previous discussion about this topic:

1) December 2015: [Idea] Add an (Index,Element) sequence to
CollectionType
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html
and
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html


2) April 2016: [Idea] Replace enumerate() with something more explicit
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html


3) September 2016: [Proposal draft] Introducing `indexed()`collections
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html


To clarify, the discussions I linked to don't all propose to remove or 
replace `enumerated()`, but they all talk about the potential confusion 
about what `enumerated()` does and does not do.


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


Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Ole Begemann via swift-evolution

On 31/01/2017 15:24, Chris Eidhof via swift-evolution wrote:

There are a couple of things that keep coming up, and a couple of
mistakes that I see people making over and over again. One of them is
that in almost every workshop, there's someone who thinks that
`enumerated()` returns a list of (index, element) pairs. This is only
true for arrays. It breaks when using array slices, or any other kind of
collection. In our workshops, I sometimes see people doing something
like `x.reversed().enumerated()`, where `x` is an array, and somehow it
produces behavior they don't understand.

A few ways I think this could be improved:

- Move enumerated to Array
- Change enumerated to return `(Index, Iterator.Element)` (this would
mean we at least need to move it to collection)
- Remove enumerated
- Keep things as is


Here are three previous discussion about this topic:

1) December 2015: [Idea] Add an (Index, Element) sequence to CollectionType
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151221/004561.html 
and 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004626.html


2) April 2016: [Idea] Replace enumerate() with something more explicit
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015074.html

3) September 2016: [Proposal draft] Introducing `indexed()` collections
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160926/027355.html

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


Re: [swift-evolution] Strings in Swift 4

2017-01-31 Thread Thorsten Seitz via swift-evolution
If I understand correctly, `1...` is not a Range but a RangeExpression which 
should not conform to Sequence and would need to be provided with a value for 
its open end to turn it into a Range.

Subscript would provide the last valid index in your first example and for your 
second example you would have to provide the desired end yourself.

Just voicing my exceptions for the different types as I cannot currently check 
their implementation.

-Thorsten 

> Am 31.01.2017 um 12:36 schrieb James Froggatt via swift-evolution 
> :
> 
> While an unbounded range doesn't need an endIndex to conform to Sequence, 
> conformance would let you iterate over it.
> 
> If someone were to iterate over it, and, for example, get the numbers [5, 6, 
> 7, 8], one could take that to mean that those numbers are part of the 
> sequence. Based on this, users could:
> 1. Be tempted to use it as an infinite range (as opposed to unbounded).
> 2. Be confused when the 7 and 8 which were just confirmed to be in the 
> sequence are ignored when subscripting.
> 
> To put it another way, it would be reasonable to expect the following to be 
> equivalent (or fail equivalently):
> 
> let x = array[sequenceOfIndices]
> let y = sequenceOfIndices.map{array[$0]}
> 
> The idea that it is infinite when used in one way but finite when used in 
> another seems very wrong.
> 
> From James
> 
>> On 31 Jan 2017, at 07:00, David Hart  wrote:
>> 
>> 
>> 
>> 
>> Sent from my iPhone
>>> On 31 Jan 2017, at 02:04, James Froggatt via swift-evolution 
>>>  wrote:
>>> 
>>> Going to try resending this - my client doesn't seem to give me a proper 
>>> email address to reply to (only some gmane mangled address which got me a 
>>> delivery failure); sorry for the lack of a direct reply.
>>> 
>>> ---
>>> 
>>> Exactly. I'm not too familiar with range subscripting on arrays, but if 
>>> it's anything like a regular Int subscript, I'd expect…
>>> 
>>> let outOfBoundsSubrange = items[items.startIndex...items.endIndex]
>>> 
>>> …to give an out of bounds error, since (in my mental model) it tries to 
>>> access items[items.endIndex].
>> 
>> Like you say below, i... doesn't have an endIndex, so it doesn't make sense 
>> to represent it as items.startIndex...items.endIndex. It's open unbounded 
>> range. So it doesn't break my mental model :)
>> 
>>> If ‘items.startIndex...’ represents an unbounded range (one with a unknown 
>>> / subscript-defined endIndex), I can't see enough use-cases for it outside 
>>> of subscripting to justify its existence as a type - it can't even conform 
>>> to sequence, since there is no endIndex, making it essentially just a 
>>> number and a promise of how APIs will use it. If we pretend an unbounded 
>>> range is infinite by conforming it to sequence, people will inevitably use 
>>> it like one.
>> 
>> Sequence does not require an endIndex. Collection does. So, as Dave shown, 
>> it can actually be very useful: see how he redefined enumerated using the 
>> unbounded range and zip? That's really cool! How about using it to make for 
>> loops act as a infinite while loop with an index?
>> 
>> var index = 0
>> while true {
>>  // break somewhere here
>> }
>> 
>> Becomes:
>> 
>> for index in 0... {
>> }
>> 
>>> If this syntax represents an infinite range, I'd expect it to similarly 
>>> give an error when used to subscript a non-infinite array-like type, but it 
>>> would at least be independently useful outside of collections as a way to 
>>> generate an infinite sequence.
>>> 
>>> 
>>> As a further point, what if we also implemented prefix comparison 
>>> operators? Which of the following looks more like an infinite range, and 
>>> which looks more like an unbounded one? I'll leave the answer up to the 
>>> reader:
>>> 
>>> let indices = >oneDigitNums.startIndex
>>> oneDigitNums[>5]
>>> 
>>> let indices = oneDigitNums.startIndex...
>>> oneDigitNums[5...]
>> 
>> I prefer the latter :) At least it uses a Range operator.
>> 
>>>  Begin Message  
>>> Group: gmane.comp.lang.swift.evolution 
>>> MsgID:  
>>> 
>>> 
 On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
  wrote:
 
 Why should that be out-of-bounds?  Whether it is out-of-bounds would
 depend on what items is.  If it's an array, that should be equivalent to
 
 let x = items[items.startIndex..>> 
>>> It seems to me that `items[0…]` would be equivalent to `items[0…Int.max]` 
>>> if we’re going to treat `0…` as an “infinite" range, no? Otherwise, we’re 
>>> either giving subscript of InfiniteRange types special behavior or we’re 
>>> making subscript ignore past-the-end indices; `”hello”.characters[0…10]` 
>>> would need to return the same as “hello”.characters[0…4]` to be consistent.
>>> 
>>> 
>>> - End Message 

Re: [swift-evolution] Removing enumerated?

2017-01-31 Thread Charlie Monroe via swift-evolution

> On Jan 31, 2017, at 3:24 PM, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hey everyone,
> 
> I've organized a number of Swift workshops over the last two years. There are 
> a couple of things that keep coming up, and a couple of mistakes that I see 
> people making over and over again. One of them is that in almost every 
> workshop, there's someone who thinks that `enumerated()` returns a list of 
> (index, element) pairs. This is only true for arrays. It breaks when using 
> array slices, or any other kind of collection. In our workshops, I sometimes 
> see people doing something like `x.reversed().enumerated()`, where `x` is an 
> array, and somehow it produces behavior they don't understand.

What is the behavior that you'd like?

for x in [1, 2, 3].reversed().enumerated() {
print(x)
}

produces (first column is the index, second the element):

(0, 3)
(1, 2)
(2, 1)

- it IMHO behaves as one would expect - it returns an index into the sequence 
that you are enumerating...

> 
> A few ways I think this could be improved:
> 
> - Move enumerated to Array
> - Change enumerated to return `(Index, Iterator.Element)` (this would mean we 
> at least need to move it to collection)
> - Remove enumerated
> - Keep things as is
> 
> In any case, just wanted to share my experience (gained from teaching 
> people). 
> 
> -- 
> Chris Eidhof
> ___
> 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] Removing enumerated?

2017-01-31 Thread Chris Eidhof via swift-evolution
Hey everyone,

I've organized a number of Swift workshops over the last two years. There
are a couple of things that keep coming up, and a couple of mistakes that I
see people making over and over again. One of them is that in almost every
workshop, there's someone who thinks that `enumerated()` returns a list of
(index, element) pairs. This is only true for arrays. It breaks when using
array slices, or any other kind of collection. In our workshops, I
sometimes see people doing something like `x.reversed().enumerated()`,
where `x` is an array, and somehow it produces behavior they don't
understand.

A few ways I think this could be improved:

- Move enumerated to Array
- Change enumerated to return `(Index, Iterator.Element)` (this would mean
we at least need to move it to collection)
- Remove enumerated
- Keep things as is

In any case, just wanted to share my experience (gained from teaching
people).

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


Re: [swift-evolution] Generalized Existentials / Type Erasers

2017-01-31 Thread David Hart via swift-evolution
Hi Chris,

The topic has been heavily discussed last year, culminating into a massing 
proposal by Austin Zheng:

https://github.com/austinzheng/swift-evolution/blob/az-existentials/proposals/-enhanced-existentials.md#nested-typealias-existential
 


The proposal was never merged and postponed for a future Swift release. This 
feature is very important for me so I reopened it earlier this month:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170102/029890.html
 


Douglas Gregor replied to this thread saying that part of the proposal 
(superclass and protocol constraints) should be proposed and implemented for 
Swift 4, but that the remaining more generalised has little chance to make it 
in time for Swift 4.

In consequence, I started a new thread with the smaller feature of superclass 
and protocol constraints:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170123/031066.html
 


Quite a few comments have already been made about the proposal so I’ll post a 
new draft soon. But please let me know if you have more comments!

David.

> On 31 Jan 2017, at 11:07, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Hi swift-evolution,
> 
> I was wondering if anything more detailed has been written about generalized 
> existentials / type erasers. I noticed that AnyCollection only delegates a 
> number of methods to its wrapped value, but often doesn't. For example, all 
> the conditionally inherited items aren't being delegated (e.g. min()). This 
> behavior was surprising to me (but makes sense once I thought about it 
> longer).
> 
> How would this work with generalized existentials? Are generalized 
> existentials in scope at all for Swift 4?
> 
> -- 
> Chris Eidhof
> ___
> 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] protocol-oriented integers (take 2)

2017-01-31 Thread Nevin Brackett-Rozinsky via swift-evolution
…rather, the remainder will fit in width min(X, Y)

Nevin

On Tuesday, January 31, 2017, Nevin Brackett-Rozinsky <
nevin.brackettrozin...@gmail.com> wrote:

> What, exactly, is the intended purpose of doubleWidthDivide?
>
> I ask because, outside of degenerate cases, a quotient and remainder will
> fit in the same size type as the operands.
>
> So widthX / widthY will have quotient that fits in width X, and remainder
> that fits in width Y.
>
> In general, we cannot assume either one would be any smaller than that.
>
> Nevin
>
>
> On Monday, January 30, 2017, Brent Royal-Gordon via swift-evolution <
> swift-evolution@swift.org
> > wrote:
>
>> > On Jan 30, 2017, at 11:31 AM, Max Moiseev  wrote:
>> >
>> > doubleWidthDivide should not return a DoubleWidth for two reasons:
>> > 1. The components of it’s return type are not high and low, but are
>> quotient and remainder instead.
>> > 2. In DoubleWidth high is T and low is T.Magnitude, which is not the
>> case for quotient and remainder.
>>
>> You're right about the return value; for `doubleWidthDivide(_:_:)`, I was
>> thinking about changing the dividend. Specifically, I'm thinking we should
>> change these to:
>>
>> static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) ->
>> DoubleWidth
>> static func doubleWidthDivide(_ lhs: DoubleWidth, _ rhs:
>> Self) -> (quotient: Self, remainder: Self)
>>
>> I'm also thinking a little bit about spelling of these operations. I'd
>> *love* to be able to call them `*` and `/` and let the type system sort
>> things out, but that would cause problems, especially for multiply (since
>> the return value is the only thing different from a normal `*`). We could
>> invent a new operator, but that would be a bit much. Could these be simply
>> `multiply` and `divide`, and we'll permit the `DoubleWidth`
>> parameter/return type to explain itself?
>>
>> I'm also thinking the second parameter should be labeled `by`, since
>> that's the way people talk about these operations. Applying both of these
>> suggestions, we'd get:
>>
>> static func multiply(_ lhs: Self, by rhs: Self) ->
>> DoubleWidth
>> static func divide(_ lhs: DoubleWidth, by rhs: Self) ->
>> (quotient: Self, remainder: Self)
>>
>> let x = Int.multiply(a, by: b)
>> let (aʹ, r) = Int.divide(x, by: b)
>> assert(a == aʹ)
>> assert(r == 0)
>>
>> Should the standard library provide extensions automatic definitions of
>> multiplication and division in terms of their double-width equivalents?
>>
>> extension FixedWidthInteger {
>> func multipliedWithOverflow(by other: Self) ->
>> (partialValue: Self, overflow: ArithmeticOverflow) {
>> let doubledResult = Self.multiply(self, by: other)
>> let overflowed = doubledResult.high !=
>> (doubledResult < 0 ? -1 : 0)
>> return (Self(bitPattern:
>> doubledResult.lowerValue), overflowed ? .overflowed : .none)
>> }
>>
>> func quotientAndRemainder(dividingBy other: Self) ->
>> (quotient: Self, remainder: Self) {
>> precondition(other != 0, "Divide by zero")
>> return Self.divide(DoubleWidth(self), by: other)
>> }
>>
>> func dividedWithOverflow(by other: Self) ->
>> (partialValue: Self, overflow: ArithmeticOverflow) {
>> guard other != 0 else { return (self,
>> .overflowed) }
>>
>> let result = Self.divide(self, by: other)
>> return (result.quotient, .none)
>> }
>>
>> static func * (lhs: Self, rhs: Self) -> Self {
>> let result = lhs.dividedWithOverflow(by: rhs)
>> precondition(result.overflow == .none,
>> "Multiplication overflowed")
>> return result.partialValue
>> }
>>
>> static func / (lhs: Self, rhs: Self) -> Self {
>> let result = lhs.quotientAndRemainder(dividingBy:
>> rhs)
>> return result.quotient
>> }
>>
>> static func % (lhs: Self, rhs: Self) -> Self {
>> let result = lhs.quotientAndRemainder(dividingBy:
>> rhs)
>> return result.remainder
>> }
>> }
>>
>> Hmm...having actually written this out, I now have a couple of concerns:
>>
>> 1. There's a lot of jumping back and forth between instance methods and
>> static methods. Can we standardize on just static methods? Or make sure
>> that the user-facing interfaces are all either operators or instance
>> methods?
>>
>> 2. There is no quotient-and-remainder-with-overflow, either regular or
>> double-width. Can we do that?
>>
>> 3. "Overflow" is not really a good description of what's happening in

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-31 Thread Nevin Brackett-Rozinsky via swift-evolution
What, exactly, is the intended purpose of doubleWidthDivide?

I ask because, outside of degenerate cases, a quotient and remainder will
fit in the same size type as the operands.

So widthX / widthY will have quotient that fits in width X, and remainder
that fits in width Y.

In general, we cannot assume either one would be any smaller than that.

Nevin


On Monday, January 30, 2017, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> > On Jan 30, 2017, at 11:31 AM, Max Moiseev  > wrote:
> >
> > doubleWidthDivide should not return a DoubleWidth for two reasons:
> > 1. The components of it’s return type are not high and low, but are
> quotient and remainder instead.
> > 2. In DoubleWidth high is T and low is T.Magnitude, which is not the
> case for quotient and remainder.
>
> You're right about the return value; for `doubleWidthDivide(_:_:)`, I was
> thinking about changing the dividend. Specifically, I'm thinking we should
> change these to:
>
> static func doubleWidthMultiply(_ lhs: Self, _ rhs: Self) ->
> DoubleWidth
> static func doubleWidthDivide(_ lhs: DoubleWidth, _ rhs:
> Self) -> (quotient: Self, remainder: Self)
>
> I'm also thinking a little bit about spelling of these operations. I'd
> *love* to be able to call them `*` and `/` and let the type system sort
> things out, but that would cause problems, especially for multiply (since
> the return value is the only thing different from a normal `*`). We could
> invent a new operator, but that would be a bit much. Could these be simply
> `multiply` and `divide`, and we'll permit the `DoubleWidth`
> parameter/return type to explain itself?
>
> I'm also thinking the second parameter should be labeled `by`, since
> that's the way people talk about these operations. Applying both of these
> suggestions, we'd get:
>
> static func multiply(_ lhs: Self, by rhs: Self) ->
> DoubleWidth
> static func divide(_ lhs: DoubleWidth, by rhs: Self) ->
> (quotient: Self, remainder: Self)
>
> let x = Int.multiply(a, by: b)
> let (aʹ, r) = Int.divide(x, by: b)
> assert(a == aʹ)
> assert(r == 0)
>
> Should the standard library provide extensions automatic definitions of
> multiplication and division in terms of their double-width equivalents?
>
> extension FixedWidthInteger {
> func multipliedWithOverflow(by other: Self) ->
> (partialValue: Self, overflow: ArithmeticOverflow) {
> let doubledResult = Self.multiply(self, by: other)
> let overflowed = doubledResult.high !=
> (doubledResult < 0 ? -1 : 0)
> return (Self(bitPattern:
> doubledResult.lowerValue), overflowed ? .overflowed : .none)
> }
>
> func quotientAndRemainder(dividingBy other: Self) ->
> (quotient: Self, remainder: Self) {
> precondition(other != 0, "Divide by zero")
> return Self.divide(DoubleWidth(self), by: other)
> }
>
> func dividedWithOverflow(by other: Self) -> (partialValue:
> Self, overflow: ArithmeticOverflow) {
> guard other != 0 else { return (self, .overflowed)
> }
>
> let result = Self.divide(self, by: other)
> return (result.quotient, .none)
> }
>
> static func * (lhs: Self, rhs: Self) -> Self {
> let result = lhs.dividedWithOverflow(by: rhs)
> precondition(result.overflow == .none,
> "Multiplication overflowed")
> return result.partialValue
> }
>
> static func / (lhs: Self, rhs: Self) -> Self {
> let result = lhs.quotientAndRemainder(dividingBy:
> rhs)
> return result.quotient
> }
>
> static func % (lhs: Self, rhs: Self) -> Self {
> let result = lhs.quotientAndRemainder(dividingBy:
> rhs)
> return result.remainder
> }
> }
>
> Hmm...having actually written this out, I now have a couple of concerns:
>
> 1. There's a lot of jumping back and forth between instance methods and
> static methods. Can we standardize on just static methods? Or make sure
> that the user-facing interfaces are all either operators or instance
> methods?
>
> 2. There is no quotient-and-remainder-with-overflow, either regular or
> double-width. Can we do that?
>
> 3. "Overflow" is not really a good description of what's happening in
> division; the value is undefined, not overflowing. Is there a better way to
> express this?
>
> 4. For that matter, even non-fixed-width division can "overflow"; should
> that concept be hoisted higher up the protocol hierarchy?
>
> 5. For *that* matter, should we simply make these operations throw instead
> of returning 

Re: [swift-evolution] Why doesn't Swift allow a variable and a function with the same name?

2017-01-31 Thread Tino Heth via swift-evolution
Afaics the motivation has been explained in detail, but actually, you even can 
declare such a variable as long as it has its own scope:

class Test {
func f(i: Int) {
print(i)
}

func g() {
let f = 1 // hey, works!
print(f)
print(self.f(i:f)) // works as well
}

var f: (Int) -> Void = f // huh?
} ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Initializers

2017-01-31 Thread Victor Petrescu via swift-evolution
I also thought at most of the issues presented before making the
suggestion. Let me adress each one (in the order of how I see their
importance) and explain my point of view:

1. Most inportant - safety: As Robert Widmann (and others) pointed out
swift is safe by default. And I love that about swift. Is the main reason I
migrated towards it. Still, I highlight the "by default" part. I am
suggesting adding a little keyword to explicit say that the developer
doesn't want to call the parent init() (let's say that keyword is 'exp').
This means my B class would become something like this:

class B:A {
exp override init() {
x = 2;
}
}

This way swift still remains safe by default. A developer can still be sure
that everything is safe unless he explicitly choosed to wave that safety
for a little performance boost. Imo, that should be the developers choice.

2. Private variables: Well... those are a pain. David Sweeris idea of a
flag sounds nice to me, but I don't know if there would be any undesired
consequences for this. Basically if that flag is not set and 'exp' a
compile error is shown.

3. Regarding the 3 points made by Jaded Geller:
- Safety (see point 1.)
- Compiler optimization to eliminate duplicate: If this is
possible/exists it would/is totally solving the issue in an elegant way. In
my test it appeared it does not exist. Is it possible to make compiler skip
the x = 1 line (personally I can't see how but maybe someone can prove me
wrong - I would really love that because it would be exactly what I need)?
- Regarding the workaround proposed: Yes, it works in the simple
particular case I exposed, but in real life cases is not practical (imagine
you have 30 variables).

4. Joe Groff says there is already a backdoor of sorts ("There already is a
backdoor of sorts. This is one of the intended use cases for
implicitly-unwrapped optionals. If you don't want to be hassled by DI,
declare a property as T! type, and it will be implicitly initialized to
nil, and trap if you try to use it as an unwrapped T without initializing
it first."): I'm assuming by T you mean generics. If that is true that may
already solve the problem but... generics are a new concept for me (first
time I really encountered and used them is now, in swift) but to my
understanding their role is to deal with cases you don't know the type. Can
you please show how to use this to work around the posted issue?

Sidenote: There may be another workaround using optionals (Joe Groff answer
made it pop in my mind) but... I know the type and value for the variable,
it is not optional or nil. Unwrapping each time someone needs it does not
look like the best solution to me.
Sidenote: Is not that strange to have a superclass to initialize to
something then the subclass to anothe value (I had multiple real cases like
this where it was helpful - example carFuel a few years back -> most cars
work on gas, but then electric cars started to raise; it is helpful to have
130 brands of cars that extends from a general brand that have carFuel as
'gas', and Tesla (for example) that inits it to 'electric'). The example I
originally posted, and the one posted in this sidenote where intentionally
oversimplified to expose the case.

P.S. Sorry for any grammatical errors and thank you for your time.

Have a great day,
Petrescu Victor

On Mon, Jan 30, 2017 at 10:36 PM, Robert Widmann 
wrote:

> This seems to contradict Swift’s goal of being safe by default
> , no?  It would make me incredibly
> uncomfortable if there were a backdoor in DI, even if that backdoor emitted
> traps when it fails.
>
> On Jan 28, 2017, at 1:07 PM, Victor Petrescu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hello,
>
> My name is Victor, been a developer (C, delphi, php, java, js) for the
> last 10 years or so and lately I had the chance to try swift. I have a
> suggestion/question regarding initializers.
>
> Sidenote: If this is not the correct mailing list for this can you please
> redirect me to the right place?
>
> Consider the following 2 classes and code:
>
> class A {
>  var x:Int
>
>  init() {
>  x = 1
>  }
> }
>
> class B : A {
> override init() {
>  super.init() // Swift FORCES this call
>  x = 2
> }
> }
>
> var a:B
> for i in 0... {
> a = B()  // Whatever... some code that inits B.
> }
>
> This results in  x = 1 then  x = 2... the x = 1 being
> totally useless in this particular case.
>
> In this case, if you don't make the super init you get a compile error.
>
>
>
> *Now... I see the use of this. It ensure that all members are initialized.
> For example if A had a private variable (another strange choice here with
> what private means in swift but I haven't thought on it yet so... maybe is
> a cool choice), the B init could not initialize it. I also understand that
> the cases when you need this minor performance gain 

Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread David Hart via swift-evolution
Makes sense now. I remove my point about removing that fix. Optional chaining 
is much more useful to have behaving as expected.

> On 31 Jan 2017, at 10:07, Alex Hoppen via swift-evolution 
>  wrote:
> 
> This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend 
> of mine pointed the following inconsistency out to me:
> 
> struct Foo {
>  func bar() {}
> }
> let foo: Foo? = Foo()
> foo?.bar() // Does not create a warning
> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
> 
> After some offline discussion at WWDC with the Swift team we decided to move 
> to a consistent model where ()?, ()??, … is always discardable since we 
> didn't want to take the convenience of foo?.bar() away (something that 
> regularly occurs with weak variables, e.g. captures in closures).
> 
> So much for the history of this feature.
> 
> – Alex
> 
> 
>> On 30 Jan 2017, at 22:58, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>> Hi all,
>> 
>> Right now, expressions that evaluates to Optional<()>, 
>> Optional>… gets special treatment when it’s unused. For example:
>> 
>> func f(s: String) {}
>> let s: String = “”
>> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
>> and unused.
>> 
>> func g() throws {}
>> try? g() // no warnings here neither.
>> 
>> This is convenient, but encourages composing map/filter/reduce, etc with 
>> side-effect-ful functions, which we have found a few cases of in our 
>> production code recently. Granted, these cases could’ve been caught with 
>> more careful code reviews. But we wouldn’t have missed them if this 
>> “feature” didn’t exist.
>> 
>> I think we should remove the special treatment so that code in the example 
>> above would generate a warning about `()?` being unused. Users can silence 
>> it manually by assigning the result to `_`. 
>> 
>> OTOH, this would undermine the convenience of `try?` when the throwing 
>> function don’t return anything.
>> 
>> What do y’all think?
>> 
>> Daniel Duan
>> ___
>> 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] Strings in Swift 4

2017-01-31 Thread James Froggatt via swift-evolution
While an unbounded range doesn't need an endIndex to conform to Sequence, 
conformance would let you iterate over it.

If someone were to iterate over it, and, for example, get the numbers [5, 6, 7, 
8], one could take that to mean that those numbers are part of the sequence. 
Based on this, users could:
1. Be tempted to use it as an infinite range (as opposed to unbounded).
2. Be confused when the 7 and 8 which were just confirmed to be in the sequence 
are ignored when subscripting.

To put it another way, it would be reasonable to expect the following to be 
equivalent (or fail equivalently):

let x = array[sequenceOfIndices]
let y = sequenceOfIndices.map{array[$0]}

The idea that it is infinite when used in one way but finite when used in 
another seems very wrong.

From James

> On 31 Jan 2017, at 07:00, David Hart  wrote:
> 
> 
> 
> 
> Sent from my iPhone
>> On 31 Jan 2017, at 02:04, James Froggatt via swift-evolution 
>>  wrote:
>> 
>> Going to try resending this - my client doesn't seem to give me a proper 
>> email address to reply to (only some gmane mangled address which got me a 
>> delivery failure); sorry for the lack of a direct reply.
>> 
>> ---
>> 
>> Exactly. I'm not too familiar with range subscripting on arrays, but if it's 
>> anything like a regular Int subscript, I'd expect…
>> 
>> let outOfBoundsSubrange = items[items.startIndex...items.endIndex]
>> 
>> …to give an out of bounds error, since (in my mental model) it tries to 
>> access items[items.endIndex].
> 
> Like you say below, i... doesn't have an endIndex, so it doesn't make sense 
> to represent it as items.startIndex...items.endIndex. It's open unbounded 
> range. So it doesn't break my mental model :)
> 
>> If ‘items.startIndex...’ represents an unbounded range (one with a unknown / 
>> subscript-defined endIndex), I can't see enough use-cases for it outside of 
>> subscripting to justify its existence as a type - it can't even conform to 
>> sequence, since there is no endIndex, making it essentially just a number 
>> and a promise of how APIs will use it. If we pretend an unbounded range is 
>> infinite by conforming it to sequence, people will inevitably use it like 
>> one.
> 
> Sequence does not require an endIndex. Collection does. So, as Dave shown, it 
> can actually be very useful: see how he redefined enumerated using the 
> unbounded range and zip? That's really cool! How about using it to make for 
> loops act as a infinite while loop with an index?
> 
> var index = 0
> while true {
>   // break somewhere here
> }
> 
> Becomes:
> 
> for index in 0... {
> }
> 
>> If this syntax represents an infinite range, I'd expect it to similarly give 
>> an error when used to subscript a non-infinite array-like type, but it would 
>> at least be independently useful outside of collections as a way to generate 
>> an infinite sequence.
>> 
>> 
>> As a further point, what if we also implemented prefix comparison operators? 
>> Which of the following looks more like an infinite range, and which looks 
>> more like an unbounded one? I'll leave the answer up to the reader:
>> 
>> let indices = >oneDigitNums.startIndex
>> oneDigitNums[>5]
>> 
>> let indices = oneDigitNums.startIndex...
>> oneDigitNums[5...]
> 
> I prefer the latter :) At least it uses a Range operator.
> 
>>  Begin Message  
>> Group: gmane.comp.lang.swift.evolution 
>> MsgID:  
>> 
>> 
>>> On Jan 30, 2017, at 11:35 AM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> Why should that be out-of-bounds?  Whether it is out-of-bounds would
>>> depend on what items is.  If it's an array, that should be equivalent to
>>> 
>>> let x = items[items.startIndex..> 
>> It seems to me that `items[0…]` would be equivalent to `items[0…Int.max]` if 
>> we’re going to treat `0…` as an “infinite" range, no? Otherwise, we’re 
>> either giving subscript of InfiniteRange types special behavior or we’re 
>> making subscript ignore past-the-end indices; `”hello”.characters[0…10]` 
>> would need to return the same as “hello”.characters[0…4]` to be consistent.
>> 
>> 
>> - End Message - 
>> 
>> 
>> 
>> From James
>> ___
>> 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] Annotation of Warnings/Errors

2017-01-31 Thread Tino Heth via swift-evolution
> One of the biggest issues that I saw while teaching Swift to newbies (most 
> had not programmed before) is confusion based on the early warnings/errors 
> that swift/xcode gives you as they type.  What would happen is that they 
> would type a variable, and it would say… “You haven’t used this variable” and 
> so they would just click the fixit because they trust the compiler more than 
> they trust themselves.  This would lead to a point where they were very 
> confused because some of the code was code they had thought through, and some 
> of it was changed by random fixits in ways they didn’t understand… and so it 
> would lead to more errors/fixits until they had errors which couldn’t be 
> fixed.


Imho this is the best example to illustrate that inflationary use of warnings 
does more harm than good, and I hope it will be fixed.

Having a bunch of conditions for warnings looks like overkill to me, and there 
are alternatives:
- Only show when building
- Only show in release builds
- Linter

That said, I'm going out on a limb and claim I already know how to write code 
and don't need basic schooling, and showing warnings before I hit compile is 
merely a distraction.

But there are also Playgrounds which seem to be an important aspect of Swift, 
especially for newbies who could really benefit from some hints.
There are no linters, no release builds, and even no regular builds for 
Playgrounds, so your model is the only one that works for them.

Bottom line:
+1 ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread Tino Heth via swift-evolution
> I think we should remove the special treatment so that code in the example 
> above would generate a warning about `()?` being unused. Users can silence it 
> manually by assigning the result to `_`. 

Imho Swift already uses warnings excessively, and giving Optional more 
significance than Void feels strange.

Shortly after the new error-handling was added, I felt irritated when I first 
used a trowing void-function and got a warning ("hu? That function has no 
result to ignore — why should I declare a variable to store void?").

I'm fine with the current situation and wouldn't undo it.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Why doesn't Swift allow a variable and a function with the same name?

2017-01-31 Thread Tino Heth via swift-evolution
> It seams like there is discussion to be had, comparing these models:
> 
>   [A] functions have simple names, and arguments have labeled tuple type 
> model
>   [B] model where we strictly require the labels for referring to n-ary 
> functions (e.g. "insert(cell:, into:)" instead of "insert")
> 
> I like [B] because it does solve cases of ambiguity, where only using the 
> base-name of the func causes the "Variable used within its own initial value” 
> described by Michael.
> 
> What are some advantages of [A]? I assume that tuple splatting (i.e. passing 
> a tuple of args when calling a n-ary function) is one of them, or is that not 
> related?


Imho B has drawbacks which count as advantages for A:

- More typing (obvious, although not that terrible)

- Can easily be confused with an actual function call (imho "(" is tightly 
coupled with the idea of "ah, that's a function that is called"):

func f(_ arg: Int) -> Int {
print(arg)
return 0
}

func f(arg: Int) -> Int {
print("Not", arg)
return arg
}

let arg = 1

let outFunc = f(arg:)
let outInt = f(arg)

- May look odd (especially if you are used to functions in math)

func g(_ a: Int, _ b: Int) -> Int {
return a + b
}

let looksLikePearl = g(:, :) // "Expected expression in list of expressions" - 
compiler doesn't like it either ;-)

> Am 31.01.2017 um 01:59 schrieb Joe Groff via swift-evolution 
> :
> 
> The ability to reference a function by only the first segment of its name is 
> likewise legacy of the original model, though it happens to be useful since 
> good naming hygiene encourages different base names for different things to 
> begin with.

+1, hope the short syntax stays the preferred choice when there is no ambiguity.

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


[swift-evolution] Generalized Existentials / Type Erasers

2017-01-31 Thread Chris Eidhof via swift-evolution
Hi swift-evolution,

I was wondering if anything more detailed has been written about
generalized existentials / type erasers. I noticed that AnyCollection only
delegates a number of methods to its wrapped value, but often doesn't. For
example, all the conditionally inherited items aren't being delegated (e.g.
min()). This behavior was surprising to me (but makes sense once I thought
about it longer).

How would this work with generalized existentials? Are generalized
existentials in scope at all for Swift 4?

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


Re: [swift-evolution] Warn about unused Optional.some(())

2017-01-31 Thread Alex Hoppen via swift-evolution
This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend 
of mine pointed the following inconsistency out to me:

struct Foo {
  func bar() {}
}
let foo: Foo? = Foo()
foo?.bar() // Does not create a warning
true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused

After some offline discussion at WWDC with the Swift team we decided to move to 
a consistent model where ()?, ()??, … is always discardable since we didn't 
want to take the convenience of foo?.bar() away (something that regularly 
occurs with weak variables, e.g. captures in closures).

So much for the history of this feature.

– Alex


> On 30 Jan 2017, at 22:58, Daniel Duan via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> Right now, expressions that evaluates to Optional<()>, 
> Optional>… gets special treatment when it’s unused. For example:
> 
> func f(s: String) {}
> let s: String = “”
> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
> and unused.
> 
> func g() throws {}
> try? g() // no warnings here neither.
> 
> This is convenient, but encourages composing map/filter/reduce, etc with 
> side-effect-ful functions, which we have found a few cases of in our 
> production code recently. Granted, these cases could’ve been caught with more 
> careful code reviews. But we wouldn’t have missed them if this “feature” 
> didn’t exist.
> 
> I think we should remove the special treatment so that code in the example 
> above would generate a warning about `()?` being unused. Users can silence it 
> manually by assigning the result to `_`. 
> 
> OTOH, this would undermine the convenience of `try?` when the throwing 
> function don’t return anything.
> 
> What do y’all think?
> 
> Daniel Duan
> ___
> 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] Why doesn't Swift allow a variable and a function with the same name?

2017-01-31 Thread Lucas Neiva via swift-evolution

> On 31 Jan 2017, at 01:59, Joe Groff via swift-evolution 
>  wrote:
> 
> To be honest, I would say that there's no "reason" for this, except as 
> lingering effects of our early "functions have simple names, and arguments 
> have labeled tuple type" model. If we had originally implemented the language 
> with its current (at least aspirational) Smalltalk-ish compound-names model, 
> we probably would have ended up allowing this, since the var and func do 
> formally have different names. The ability to reference a function by only 
> the first segment of its name is likewise legacy of the original model, 
> though it happens to be useful since good naming hygiene encourages different 
> base names for different things to begin with.

It seams like there is discussion to be had, comparing these models:

[A] functions have simple names, and arguments have labeled tuple type 
model
[B] model where we strictly require the labels for referring to n-ary 
functions (e.g. "insert(cell:, into:)" instead of "insert")

---

> Example that does not compile:
> 
>let randomArray = randomArray(withCapacity: 4096)

I like [B] because it does solve cases of ambiguity, where only using the 
base-name of the func causes the "Variable used within its own initial value” 
described by Michael.

What are some advantages of [A]? I assume that tuple splatting (i.e. passing a 
tuple of args when calling a n-ary function) is one of them, or is that not 
related?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] The lack of namespaces is leading people astray

2017-01-31 Thread Pranshu Goyal via swift-evolution
+1

On 31 January 2017 at 11:32, Russ Bishop via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Jan 30, 2017, at 5:55 AM, Tuur Anton via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> The lack of namespaces is making people create all kinds of "design
> patterns".
>
>
> What do you think?
>
>
> I’ve used languages with namespaces for many years. I don’t find
> multi-level namespaces to be much of an improvement over a single-level
> namespace in most cases. On the contrary, I find it much simpler to avoid
> hunting around importing a hundred namespaces. This is what you end up with:
>
> using System;
> using System.Collections.Generic;
> using System.Linq;
> using System.Runtime.Serialization;
> using System.ServiceModel;
> using System.ServiceModel.Web;
> using System.Text;
> using System.Data;
> using System.Data.SqlClient;
> using System.Web;
> using System.Net;
> using System.Net.HttpClient;
>
>
>
> The only thing we really need in Swift is the ability to have a Private
> submodule, especially for mixed-mode frameworks.
>
>
> Russ
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>


-- 
*Pranshu Goyal*
*iOS Developer*
*tlkn*
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Proposal to improve C pointer type import

2017-01-31 Thread Florent Bruneau via swift-evolution
Hi swift-evolution, 

For the last few weeks, I've been working on introducing some Swift in a pure-C 
codebase. While the Clang importer makes the process quite smooth, there are 
still some rough edges.

Here is a (lengthy) proposal resulting from that experience.
Rendered version: 
https://gist.github.com/Fruneau/fa83fe87a316514797c1ee2e5012

Introduction
===

Directly importing C APIs is a core feature of the Swift compiler. In that 
process, C pointers are systematically imported as `Unsafe*Pointer` swift 
objects. However, in C we make the distinction between pointers that reference 
a single object, and those pointing to an array of objects. In the case of a 
single object of type `T`, the Swift compiler should be able to import the 
parameter `T *` as a `inout T`, and `T const *` as `T`. Since the compiler 
cannot makes the distinction between pointer types by itself, we propose to add 
an attribute of C pointer for that purpose.

Motivation
===

Let consider the following C API:

```c
typedef struct sb_t {
char * _Nonnull data;
int len;
int size;
} sb_t;

/** Append the string \p str to \p sb. */
void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);

/** Append the content of \p other to \p sb. */
void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);

/** Returns the amount of available memory of \p sb. */
int sb_avail(const sb_t * _Nonnull sb);
```

This is imported in Swift as follow:

```swift
struct sb_t {
var data: UnsafeMutablePointer
var len: Int32
var size: Int32
}

func sb_adds(_ sb: UnsafeMutablePointer, _ str: UnsafePointer)
func sb_addsb(_ sb: UnsafeMutablePointer, _ other: UnsafePointer)
func sb_avail(_ sb: UnsafePointer) -> Int32
```

`sb_adds()` takes two pointers: the first one is supposed to point to a single 
object named `sb` that will be mutated in order to add the content of `str` 
which points to a c-string. So we have two kinds of pointers: the first points 
to a single object, the second to a buffer. But both are represented using 
`Unsafe*Pointer`. Swift cannot actually make the difference between those two 
kind of pointers since the C language provides no way to express it.

`sb_addsb()` takes two objects of type `sb_t`. The first is mutated by the 
function by appending the content of the second one, which is `const`. The 
constness is properly reflected in Swift. However, the usage of the imported 
API is Swift might be surprising since Swift requires usage of an `inout` 
parameter in order to build an `Unsafe*Pointer` object:

```swift
var sb = sb_t(...)
let sb2 = sb_t(...)
sb_addsb(, ) // error: cannot pass immutable value as inout argument: 
'sb2' is a 'let' constant
sb_addsb(, sb2) // cannot convert value of type 'sb_t' to expected argument 
type 'UnsafePointer!'

var sb3 = sb_t(...)
sb_addsb(, ) // works
```

```swift
sb_avail() // cannot convert value of type 'sb_t' to expected argument type 
'UnsafePointer!'
```


However, Swift also provides the `swift_name()` attribute that allows remapping 
a C function to a Swift method, which includes mapping one of the parameter to 
`self:`:

```c 
__attribute__((swift_name("sb_t.add(self:string:)")))
void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);
__attribute__((swift_name("sb_t.add(self:other:)")))
void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);
__attribute__((swift_name("sb_t.avail(self:)")))
int sb_avail(const sb_t * _Nonnull sb);
```

```swift
struct sb_t {
var data: UnsafeMutablePointer
var len: Int32
var size: Int32

mutating func add(string: UnsafePointer)
mutating func add(other: UnsafePointer)
func avail() -> Int32
}
```

With that attribute used, there is no need to convert the parameter mapped to 
`self:` to an `Unsafe*Pointer`. As a consequence, we have an improved API:

```swift
sb2.avail() // This time it works!
```

But we also have some inconsistent behavior since only `self:` is affected by 
this:

```swift
sb.add(other: )  // error: cannot pass immutable value as inout argument: 
'sb2' is a 'let' constant
sb.add(other: sb2) // cannot convert value of type 'sb_t' to expected argument 
type 'UnsafePointer!'
```


What we observe here is that mapping an argument to `self:` is enough for the 
compiler to be able to change its semantics. As soon as it knows the pointer is 
actually the pointer to a single object, it can deal with it without exposing 
it as an `Unsafe*Pointer`, making the API safer and less surprising.


Proposed solution


A new qualifier could be added to inform the compiler that a pointer points to 
a single object. Then the Swift compiler could use that new piece of the 
information to generate API that use directly the object type instead of the 
pointer type. We propose the introduction of a new qualifier named `_Ref`, 
semantically similar to a C++ reference. That is:

* `_Ref` is applied with the same grammar as the `_Nonnull`,  `_Nullable`, 
family
* A pointer