Re: [swift-evolution] Throws? and throws!

2017-01-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 10:10 PM, Jonathan Hull  wrote:

> And finally, even if an operator function could fail in multiple ways
> (we're really getting to very hypothetical hypotheticals here), writing
> `try!` all the time might look silly and non-Swift users might then mock
> the language, but I dispute the contention that it would make things
> "unbearable.”
>
>
> The whole point of ‘try’/’try!’ is to make the user consider how to handle
> the error cases.  If it gets used everywhere, then you have a boy who cried
> wolf situation where it is seen as noise and ignored… which definitely
> affects usability. (Take Windows' error dialogs as an example of this
> phenomenon).
>
>
In a hypothetical world where + was throwing, that would be a fair point,
and it would be something to balance against Greg's argument that `try!`
and `!` have value because they show all potential crash points at the
point of use. However, as this is very much a hypothetical, the more
salient point here is that there _aren't_ so many things that have multiple
meaningfully distinct ways of recovering from error.

In this present version of Swift, practical experience shows that if
anything people pay great amounts of attention (maybe too much) to
statements with `!`, even so far as to try to forbid it in their house
style (definitely too extreme, IMO)! Meanwhile, `try?` simply can't be
ignored because the type system makes you unwrap the result at some point
down the line.

On Jan 14, 2017, at 7:29 PM, Xiaodi Wu  wrote:
>
> On Sat, Jan 14, 2017 at 8:03 PM, Jonathan Hull  wrote:
>
>> My intended framing of this does not seem to be coming across in my
>> arguments.  I am not thinking of this as a way to avoid typing ‘try!’ or
>> ‘try?’.  This is not intended to replace any of the current uses of
>> ‘throws’.  Rather, it is intended to replace trapping and nil-returning
>> functions where converting it to throw would be burdensome in the most
>> common use cases, but still desirable in less common use cases.  In my
>> mind, it is only enabling the author to provide extra information and
>> flexibility, compared to the current behavior.
>>
>> For example, let’s say I have a failable initializer, which could fail
>> for 2 or 3 different reasons, and that the vast majority of use-cases I
>> only care whether it succeeded or not (which is why nil-returning was
>> chosen)… but there may be a rare case or two where I really would prefer to
>> probe deeper (and changing it to a throwing initializer would inhibit the
>> majority cases).  Then using ’throws?’ allows the primary usage to remain
>> unchanged, while allowing users to opt-in to throwing behavior when desired.
>>
>> Right now I end up making multiple functions, which are identical except
>> for throw vs nil-return, and must now be kept in sync.  I’ll admit it isn’t
>> terribly common, but it has come up enough that I think it would still be
>> useful.
>>
>
> As you say, I think this is a pretty niche use case. When you are in
> control of the code, it's trivial to write a second function that wraps the
> throwing function, returning an optional value on error. The only thing
> you'd need to keep in sync would be the declaration, not the function body,
> and that isn't truly onerous on the rare occasion when this is at issue.
>
>
>> The other argument I will make is one of symmetry.  We have 3 different
>> types of error handling in swift: throwing, optional-returns, and trapping.
>>
>
> As the Error Handling Rationale document has pointed out, these three
> different types of error handling are meant for different _kinds_ of error.
> The idea is that ideally the choice of what kind of error handling to use
> shouldn't be down to taste or other arbitrary criteria, but should reflect
> whether we're dealing with a recoverable error (throws), simple domain
> error (return nil), or logical error (trap). That much can be determined at
> the point of declaration. At the use site, there are tools to allow the end
> user to handle these errors in a variety of ways, but there is a logic
> behind allowing conversions between some and not all combinations:
>
> * A logical error is meant to be unrecoverable and thus cannot be
> converted to either nil or throw. To call a function that traps is to
> assert that the function's preconditions are met. If it's a possibility
> that the preconditions cannot be met, it should be handled before calling
> the function. A trap represents a programming mistake that should be fixed
> by changing the code so as not to trap. There are adequate solutions to the
> few instances where an error that currently traps might not be always have
> to be fatal: in the case of array indices, for instance, there's been
> proposals to allow more lenient subscripting that don't trap, at the cost
> of extra overhead--of course, you can already implement this for yourself
> in an extension.
>
> * A simple domain error 

Re: [swift-evolution] Throws? and throws!

2017-01-14 Thread Jonathan Hull via swift-evolution
> And finally, even if an operator function could fail in multiple ways (we're 
> really getting to very hypothetical hypotheticals here), writing `try!` all 
> the time might look silly and non-Swift users might then mock the language, 
> but I dispute the contention that it would make things "unbearable.”

The whole point of ‘try’/’try!’ is to make the user consider how to handle the 
error cases.  If it gets used everywhere, then you have a boy who cried wolf 
situation where it is seen as noise and ignored… which definitely affects 
usability. (Take Windows' error dialogs as an example of this phenomenon).



> On Jan 14, 2017, at 7:29 PM, Xiaodi Wu  wrote:
> 
> On Sat, Jan 14, 2017 at 8:03 PM, Jonathan Hull  > wrote:
> My intended framing of this does not seem to be coming across in my 
> arguments.  I am not thinking of this as a way to avoid typing ‘try!’ or 
> ‘try?’.  This is not intended to replace any of the current uses of ‘throws’. 
>  Rather, it is intended to replace trapping and nil-returning functions where 
> converting it to throw would be burdensome in the most common use cases, but 
> still desirable in less common use cases.  In my mind, it is only enabling 
> the author to provide extra information and flexibility, compared to the 
> current behavior.
> 
> For example, let’s say I have a failable initializer, which could fail for 2 
> or 3 different reasons, and that the vast majority of use-cases I only care 
> whether it succeeded or not (which is why nil-returning was chosen)… but 
> there may be a rare case or two where I really would prefer to probe deeper 
> (and changing it to a throwing initializer would inhibit the majority cases). 
>  Then using ’throws?’ allows the primary usage to remain unchanged, while 
> allowing users to opt-in to throwing behavior when desired.
> 
> Right now I end up making multiple functions, which are identical except for 
> throw vs nil-return, and must now be kept in sync.  I’ll admit it isn’t 
> terribly common, but it has come up enough that I think it would still be 
> useful.
> 
> As you say, I think this is a pretty niche use case. When you are in control 
> of the code, it's trivial to write a second function that wraps the throwing 
> function, returning an optional value on error. The only thing you'd need to 
> keep in sync would be the declaration, not the function body, and that isn't 
> truly onerous on the rare occasion when this is at issue.
> 
> 
> The other argument I will make is one of symmetry.  We have 3 different types 
> of error handling in swift: throwing, optional-returns, and trapping.
> 
> As the Error Handling Rationale document has pointed out, these three 
> different types of error handling are meant for different _kinds_ of error. 
> The idea is that ideally the choice of what kind of error handling to use 
> shouldn't be down to taste or other arbitrary criteria, but should reflect 
> whether we're dealing with a recoverable error (throws), simple domain error 
> (return nil), or logical error (trap). That much can be determined at the 
> point of declaration. At the use site, there are tools to allow the end user 
> to handle these errors in a variety of ways, but there is a logic behind 
> allowing conversions between some and not all combinations:
> 
> * A logical error is meant to be unrecoverable and thus cannot be converted 
> to either nil or throw. To call a function that traps is to assert that the 
> function's preconditions are met. If it's a possibility that the 
> preconditions cannot be met, it should be handled before calling the 
> function. A trap represents a programming mistake that should be fixed by 
> changing the code so as not to trap. There are adequate solutions to the few 
> instances where an error that currently traps might not be always have to be 
> fatal: in the case of array indices, for instance, there's been proposals to 
> allow more lenient subscripting that don't trap, at the cost of extra 
> overhead--of course, you can already implement this for yourself in an 
> extension.
> 
> * A simple domain error fails in only one obvious way and doesn't need an 
> error; the end user can always decide that a failure should be handled by 
> trapping using `!`--in essence, the user is asserting that the occurrence of 
> a simple domain error at that use site is a logical error. It shouldn't be 
> useful to convert nil to an error, because a simple domain error should be 
> able to fail in only one way; if the function fails in more than one way, the 
> function should throw, as it's no longer a simple domain error.
> 
> * A recoverable error can fail in one or more ways, and how you recover may 
> depend on how it failed; a user can always decide that they'll always recover 
> in the same way by using `try?`, or they can assert that it's a logical error 
> to fail at all using `try!`. The choice is up to the user.
> 
> As 

Re: [swift-evolution] Throws? and throws!

2017-01-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 8:03 PM, Jonathan Hull  wrote:

> My intended framing of this does not seem to be coming across in my
> arguments.  I am not thinking of this as a way to avoid typing ‘try!’ or
> ‘try?’.  This is not intended to replace any of the current uses of
> ‘throws’.  Rather, it is intended to replace trapping and nil-returning
> functions where converting it to throw would be burdensome in the most
> common use cases, but still desirable in less common use cases.  In my
> mind, it is only enabling the author to provide extra information and
> flexibility, compared to the current behavior.
>
> For example, let’s say I have a failable initializer, which could fail for
> 2 or 3 different reasons, and that the vast majority of use-cases I only
> care whether it succeeded or not (which is why nil-returning was chosen)…
> but there may be a rare case or two where I really would prefer to probe
> deeper (and changing it to a throwing initializer would inhibit the
> majority cases).  Then using ’throws?’ allows the primary usage to remain
> unchanged, while allowing users to opt-in to throwing behavior when desired.
>
> Right now I end up making multiple functions, which are identical except
> for throw vs nil-return, and must now be kept in sync.  I’ll admit it isn’t
> terribly common, but it has come up enough that I think it would still be
> useful.
>

As you say, I think this is a pretty niche use case. When you are in
control of the code, it's trivial to write a second function that wraps the
throwing function, returning an optional value on error. The only thing
you'd need to keep in sync would be the declaration, not the function body,
and that isn't truly onerous on the rare occasion when this is at issue.


> The other argument I will make is one of symmetry.  We have 3 different
> types of error handling in swift: throwing, optional-returns, and trapping.
>

As the Error Handling Rationale document has pointed out, these three
different types of error handling are meant for different _kinds_ of error.
The idea is that ideally the choice of what kind of error handling to use
shouldn't be down to taste or other arbitrary criteria, but should reflect
whether we're dealing with a recoverable error (throws), simple domain
error (return nil), or logical error (trap). That much can be determined at
the point of declaration. At the use site, there are tools to allow the end
user to handle these errors in a variety of ways, but there is a logic
behind allowing conversions between some and not all combinations:

* A logical error is meant to be unrecoverable and thus cannot be converted
to either nil or throw. To call a function that traps is to assert that the
function's preconditions are met. If it's a possibility that the
preconditions cannot be met, it should be handled before calling the
function. A trap represents a programming mistake that should be fixed by
changing the code so as not to trap. There are adequate solutions to the
few instances where an error that currently traps might not be always have
to be fatal: in the case of array indices, for instance, there's been
proposals to allow more lenient subscripting that don't trap, at the cost
of extra overhead--of course, you can already implement this for yourself
in an extension.

* A simple domain error fails in only one obvious way and doesn't need an
error; the end user can always decide that a failure should be handled by
trapping using `!`--in essence, the user is asserting that the occurrence
of a simple domain error at that use site is a logical error. It shouldn't
be useful to convert nil to an error, because a simple domain error should
be able to fail in only one way; if the function fails in more than one
way, the function should throw, as it's no longer a simple domain error.

* A recoverable error can fail in one or more ways, and how you recover may
depend on how it failed; a user can always decide that they'll always
recover in the same way by using `try?`, or they can assert that it's a
logical error to fail at all using `try!`. The choice is up to the user.

As far as I can tell, `throws?` and `throws!` do not change these choices;
it simply says that a recoverable error should be handled by default as a
simple domain error or a logical error, which in the Swift error handling
model should be up to the author who's using the function and not the
author who's declaring it.


> There is already some ability to convert between these:
>
> If you have a throwing function:
> ‘try?’ allows you to convert to optional-return
> ‘try!’ allows you to convert to trapping
>
> If you have an optional-return:
> ‘!’ allows you to convert to trapping
> you are unable to convert to throwing (because it requires extra info
> which isn’t available)
>
> If you have a trapping function, you are unable to convert to either.
>
> With ‘throws?’ you have an optional return which you can convert to
> throwing with ‘try’
>
> With 

Re: [swift-evolution] Support for assertions/preconditions that sometimes fail.

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

on Sat Jan 14 2017, Tony Allevato  wrote:

> This sounds like a problem that a third-party logging API could handle
> easily, and there's nothing about Swift's current implementation blocking
> you or someone else from writing one.
>
> It feels like a fairly specialized use case—it's hard to see it being
> fundamental enough to argue that it be part of the standard library.

It's a very interesting idea, but as Tony notes, it's fairly
specialized.  More importantly, it's completely untested.  To clarify
our scope here,

  In general, any APIs proposed for the standard library should have
  broad applicability, and whenever possible the ideas should have
  precedent in a real existing implementation that many people have
  found useful.

That argues for doing what Tony suggests—implement your idea, use it,
put out a SwiftPM package, and refine it with the help of your users'
feedback—before bringing it back to Swift-evolution.

> On Sat, Jan 14, 2017 at 5:12 PM Amir Michail via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> > On Jan 14, 2017, at 8:00 PM, Saagar Jha  wrote:
>> >
>> > Why not just add a // TODO or // FIXME comment?
>> >
>>
>> There is no bug. Moreover, you want something that actually executes and
>> that can give you useful information when the program finishes running.
>>
>> > Saagar Jha
>> >
>> >> On Jan 14, 2017, at 4:10 PM, Amir Michail via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >>
>> >> It’s quite common for an assertion/precondition that you thought should
>> hold actually does not yet there is no bug. In that case, you might want to
>> remind yourself of this fact by commenting out the assertion/precondition
>> (instead of deleting it) so that you don’t make the same mistake in the
>> future by inserting such assertions/preconditions into the code.
>> >>
>> >> However, it would be nice to have explicit support for
>> assertions/preconditions that don’t always hold where there is no bug.
>> >>
>> >> For example:
>> >>
>> >> preconditionNotAlwaysTrue( list.isEmpty )
>> >>
>> >> When your app finishes running, the IDE could show you all such
>> preconditions/assertions that you thought fail sometimes that did not fail
>> in that particular run. In that case, you might consider switching them to
>> normal preconditions/assertions provided your code has now evolved to the
>> point where they always hold.
>> >> ___
>> >> 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
>

Cheers,

-- 
-Dave

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


Re: [swift-evolution] Range and ClosedRange

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

on Fri Jan 13 2017, Xiaodi Wu  wrote:

> On Fri, Jan 13, 2017 at 2:05 PM, Max Moiseev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> FWIW, the common RangeProtocol unifying both Range and ClosedRange existed
>> for a while when the new collection indexing model was being implemented.
>>
>> Here is the commit removing it: https://github.com/apple/
>> swift/pull/2108/commits/8e886a3bdded61e266678704a13edce00a4a8867
>>
>> Max
>>
>
> From the commit: "The RangeProtocol was a very weak and fragile abstraction
> because it didn't specify the interpretation of the endpoints.  To write a
> non-trivial algorithm, one usually needed to consult that information."
>
> As I argued (perhaps inarticulately) above, I think it may be worthwhile
> revisiting the abstraction once conditional conformances become possible.
> We can say more about the relationship between the endpoints of half-open
> and closed _countable_ ranges than we can of uncountable ones.

Yes, here's my plan (pending approval by this list of course):

1. Get rid of Countable[Closed]Range and use conditional conformance
   (when we get it) to make [Closed]Range conform to Collection when
   appropriate.
  
   1a. typealias CountableRange where ... = Range for backward
   compatibility.  Similarly for CountableClosedRange.
   
2. Implement
   
https://github.com/apple/swift-evolution/blob/master/proposals/0132-sequence-end-ops.md
   This is a good proposal, badly formatted (sorry!)  It includes a
   protocol RangeExpression, to which the ranges conform.  Making this
   work really cleanly depends on having generic subscripts.

>> On Jan 12, 2017, at 12:11 PM, David Hart via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hello,
>>
>> Since the release of Swift 3, I’ve seen quite a few people (me included)
>> experience a lot of friction with the new types for representing ranges.
>> I’ve seen people confused when writing an API that takes a Range as
>> argument but then can’t pass in a ClosedRange. Sometimes this can be fixed
>> because the API should be written against a more general protocol, but
>> sometimes that’s not the case.
>>
>> Those new types definitely seem to cause more problems than they fixed
>> (the Int.max problem). Has the Standard Library team put any thought into
>> this?
>>
>> Regards,
>> David.
>> ___
>> 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
>

-- 
-Dave

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


Re: [swift-evolution] Throws? and throws!

2017-01-14 Thread Jonathan Hull via swift-evolution
My intended framing of this does not seem to be coming across in my arguments.  
I am not thinking of this as a way to avoid typing ‘try!’ or ‘try?’.  This is 
not intended to replace any of the current uses of ‘throws’.  Rather, it is 
intended to replace trapping and nil-returning functions where converting it to 
throw would be burdensome in the most common use cases, but still desirable in 
less common use cases.  In my mind, it is only enabling the author to provide 
extra information and flexibility, compared to the current behavior.

For example, let’s say I have a failable initializer, which could fail for 2 or 
3 different reasons, and that the vast majority of use-cases I only care 
whether it succeeded or not (which is why nil-returning was chosen)… but there 
may be a rare case or two where I really would prefer to probe deeper (and 
changing it to a throwing initializer would inhibit the majority cases).  Then 
using ’throws?’ allows the primary usage to remain unchanged, while allowing 
users to opt-in to throwing behavior when desired.

Right now I end up making multiple functions, which are identical except for 
throw vs nil-return, and must now be kept in sync.  I’ll admit it isn’t 
terribly common, but it has come up enough that I think it would still be 
useful.


The other argument I will make is one of symmetry.  We have 3 different types 
of error handling in swift: throwing, optional-returns, and trapping.  There is 
already some ability to convert between these:

If you have a throwing function:
‘try?’ allows you to convert to optional-return
‘try!’ allows you to convert to trapping

If you have an optional-return:
‘!’ allows you to convert to trapping
you are unable to convert to throwing (because it requires extra info 
which isn’t available)

If you have a trapping function, you are unable to convert to either.

With ‘throws?’ you have an optional return which you can convert to throwing 
with ‘try’

With ‘throws!’ you have a trapping function where:
‘try?’ allows you to convert to optional-return
‘try’ allows you to convert to throwing


Thus, ‘throws?’ and ‘throws!’ allow you provide optional-return and trapping 
functions where extra information is provided so that it is possible to convert 
to throwing when desired.  In cases where this conversion is not appropriate, 
the author would simply continue to use the current methods.

Basically it is useful in designs where optional-return or trapping were 
ultimately chosen, but there was also a strong case to be made for making it a 
throwing function.  I think the fears of people using it instead of ‘throws’ 
are unfounded because they already have the ability to use optionals or 
trapping… this just mitigates some of the losses from those choices. 

Does that make more sense?  

Thanks,
Jon



> On Jan 12, 2017, at 5:34 PM, Greg Parker  wrote:
> 
> 
>> On Jan 12, 2017, at 4:46 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>>> On Thu, Jan 12, 2017 at 6:27 PM, Jonathan Hull >> > wrote:
>>> 
>>> Also, ‘try’ is still required to explicitly mark a potential error 
>>> propagation point, which is what it was designed to do.  You don’t have 
>>> ‘try’ with the variants because it is by default no longer a propagation 
>>> point (unless you make it one explicitly with ’try’).
>> 
>> If this is quite safe and more convenient, why then shouldn't it be the 
>> behavior for `throws`? (That is, why not just allow people to call throwing 
>> functions without `try` and crash if the error isn't caught? It'd be a 
>> purely additive proposal that's backwards compatible for all currently 
>> compiling code.)
> 
> Swift prefers that potential runtime crash points be visible in the code. You 
> can ignore a thrown error and crash instead, but the code will say `try!`. 
> You can force-unwrap an Optional and crash if it is nil, but the code will 
> say `!`. 
> 
> Allowing `try` to be omitted would obscure those crash points from humans 
> reading the code. It would no longer be possible to read call sites and be 
> able to distinguish which ones might crash due to an uncaught error.
> 
> (There are exceptions to this rule. Ordinary arithmetic and array access are 
> checked at runtime, and the default syntax is one that may crash.)
> 
> 
> -- 
> Greg Parker gpar...@apple.com  Runtime 
> Wrangler
> 
> 

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


Re: [swift-evolution] Support for assertions/preconditions that sometimes fail.

2017-01-14 Thread Tony Allevato via swift-evolution
This sounds like a problem that a third-party logging API could handle
easily, and there's nothing about Swift's current implementation blocking
you or someone else from writing one.

It feels like a fairly specialized use case—it's hard to see it being
fundamental enough to argue that it be part of the standard library.

On Sat, Jan 14, 2017 at 5:12 PM Amir Michail via swift-evolution <
swift-evolution@swift.org> wrote:

>
> > On Jan 14, 2017, at 8:00 PM, Saagar Jha  wrote:
> >
> > Why not just add a // TODO or // FIXME comment?
> >
>
> There is no bug. Moreover, you want something that actually executes and
> that can give you useful information when the program finishes running.
>
> > Saagar Jha
> >
> >> On Jan 14, 2017, at 4:10 PM, Amir Michail via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >> It’s quite common for an assertion/precondition that you thought should
> hold actually does not yet there is no bug. In that case, you might want to
> remind yourself of this fact by commenting out the assertion/precondition
> (instead of deleting it) so that you don’t make the same mistake in the
> future by inserting such assertions/preconditions into the code.
> >>
> >> However, it would be nice to have explicit support for
> assertions/preconditions that don’t always hold where there is no bug.
> >>
> >> For example:
> >>
> >> preconditionNotAlwaysTrue( list.isEmpty )
> >>
> >> When your app finishes running, the IDE could show you all such
> preconditions/assertions that you thought fail sometimes that did not fail
> in that particular run. In that case, you might consider switching them to
> normal preconditions/assertions provided your code has now evolved to the
> point where they always hold.
> >> ___
> >> 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-14 Thread Dave Abrahams via swift-evolution

on Sat Jan 14 2017, Benjamin Spratling  wrote:

> I notice the BinaryInteger's func word(at n: Int) -> UInt function
> expects a 2's complement representation.  Do you expect that "BigInt"
> will be implemented with 2's complement?  

Ah, this is an excellent question, excellently phrased!

We designed it so BigInt could use 2's complement (see
DoubleWidth, which works that way), which should be faster than
sign-magnitude...

BUT: I hadn't really considered that if existing bignum libraries use
sign-magnitude, we'll want to be able to efficiently use their
representations, so we need to make sure the protocols don't force those
representations to be inefficient.

> As a nonmutating function, I would think any implementation from a 1's
> complement big int would result in O(n^2) unless the BigInt were
> designed with scratch space where it could store the intermediate
> values of that representation.  

Oh... you mean that word(at:) itself would be linear, and thus
algorithms that iterate the words linearly would be O(N^2)...  yuck.

So far, the only algorithm we have using word(at:) is this one, and
https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L2191
presumably we could adapt it to sign-magnitude by expanding the
BinaryInteger protocol with a static var that indicates which
representation is used.

  enum Representation { 
twosComplement, signMagnitude, /*onesComplement?*/ 
  }
  static var representation: Representation { get }

Now, the other algorithms that I can anticipate would use word(at:) are
basically... the ones you'd have to implement to build BigInt, so I
guess this change would be OK.

Supporting sign-magnitude complicates generic programming with these
protocols, though, so I want to be really sure we need to do this before
we take the plunge.

> I only ask because just last week I was designing an arbitrary-width
> float type in 1's complement, well, really I kept the sign bit in a
> separate Bool.  

Sounds like sign-magnitude rather than 1's complement if I remember my
complements correctly.

> Of course, I recognize the value of being able to write integer init
> code from a 2's complement representation, I'm just curious if there's
> a way to allow this function to be more efficient for alternate
> representations.
>
> I love that there's a DoubleWidth type, having coded some arbitrary
> precision arithmetic, that's always a downer going from generic code
> to having to pick a specific "big enough" result type.
>
> I'm glad the % operator got moved.  It really did stand out as not
> part of floating points.
>
> Trailing zeros looks like a sensible optimization.
>
> I agree with moving the shift operators, I like that you've called out
> the notion of an infinite shift.  

I don't think we ever meant to say anything about infinite shifts!

> I can't say I fully understood the use of the separate mask vs. smart
> shift operators, but I'll take another read in the next few days and
> see if I understand why they exist.

You're not alone it appears.  We need to clarify that in the text,
obviously.  The smart shift operators are there to give you sensible
semantics without undefined behavior or traps in the cases that have
logically computable answers.  The masking shifts are there for
performance in the rare cases where smart shifting with a non-literal
shift amount introduces non-negligible overheads (testing and branching
to handle overshifts and negative shift amounts).  

Obviously you have to know that the masking behavior is benign in your
use case when using masking shifts in an operation.  I made the mistake
of using a masking shift to optimize some code the other day where the
shift amount could be equal to the full width of the value being
shifted.  I ended up widening the LHS before doing the shift and then
truncating back to the width, but that's only because I was writing
performance-critical code.  The smart shift would have “just worked.”

> I know this PR does not address the BitInt implementation, but do you
> have one?

I know someone that implemented one... using sign-magnitude, actually,
and his word(at:) implementation has the linear cost problem.  I'll ask
him to post a link.

>
>
> I'm glad to see this moving forward.
>
> -Ben Spratling
>
>> On Jan 14, 2017, at 2:00 AM, Rien via swift-evolution 
>>  wrote:
>> 
>> +1
>> 
>> Any change of including “ranged integers”?
>> I.e. an integer with a value that must fit in a predefined range?
>> 
>> Regards,
>> Rien
>> 
>> Site: http://balancingrock.nl
>> Blog: http://swiftrien.blogspot.com
>> Github: http://github.com/Swiftrien
>> Project: http://swiftfire.nl
>> 
>> 
>> 
>> 
>>> On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution 
>>>  wrote:
>>> 
>>> Hi everyone,
>>> 
>>> Back in June 2016 we discussed the new design of the integer types for the 
>>> standard library. It even resulted 

Re: [swift-evolution] Support for assertions/preconditions that sometimes fail.

2017-01-14 Thread Amir Michail via swift-evolution

> On Jan 14, 2017, at 8:00 PM, Saagar Jha  wrote:
> 
> Why not just add a // TODO or // FIXME comment?
> 

There is no bug. Moreover, you want something that actually executes and that 
can give you useful information when the program finishes running.

> Saagar Jha
> 
>> On Jan 14, 2017, at 4:10 PM, Amir Michail via swift-evolution 
>>  wrote:
>> 
>> It’s quite common for an assertion/precondition that you thought should hold 
>> actually does not yet there is no bug. In that case, you might want to 
>> remind yourself of this fact by commenting out the assertion/precondition 
>> (instead of deleting it) so that you don’t make the same mistake in the 
>> future by inserting such assertions/preconditions into the code.
>> 
>> However, it would be nice to have explicit support for 
>> assertions/preconditions that don’t always hold where there is no bug.
>> 
>> For example:
>> 
>> preconditionNotAlwaysTrue( list.isEmpty )
>> 
>> When your app finishes running, the IDE could show you all such 
>> preconditions/assertions that you thought fail sometimes that did not fail 
>> in that particular run. In that case, you might consider switching them to 
>> normal preconditions/assertions provided your code has now evolved to the 
>> point where they always hold.
>> ___
>> 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-14 Thread Dave Abrahams via swift-evolution

Responding to both Jacob and Xiaodi here; thanks very much for your
feedback!

on Sat Jan 14 2017, Xiaodi Wu  wrote:

> On Sat, Jan 14, 2017 at 1:32 AM, Jacob Bandes-Storch via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Great work, all. I'm not sure I ever commented on SE-0104, so I've read
>> through this one more carefully. Here are some things that came to mind:
>>
>> *## Arithmetic*
>>
>> Why are ExpressibleByIntegerLiteral and init?(exactly:)
>> required? I could understand needing access to 0, but this could be
>> provided by a static property or nullary initializer. It doesn't seem like
>> all types supporting arithmetic operations would necessarily be convertible
>> from an arbitrary binary integer.
>>
>>
>> I tried to evaluate the Arithmetic protocol by considering what it means
>> for higher-dimensional types such as CGPoint and CGVector. My use case was
>> a linear interpolation function:
>>
>> func lerp(from a: T, to b: T, by ratio: T) -> T {
>> return a + (b - a) * ratio
>> }
>>
>> If I've read the proposal correctly, this definition works for integer and
>> floating-point values. But we can't make it work properly for CGVector (or,
>> perhaps less mathematically correct but more familiar, CGPoint). It's okay
>> to define +(CGVector, CGVector) and -(CGVector, CGVector), but *(CGVector,
>> CGVector) and /(CGVector, CGVector) don't make much sense. What we really
>> want is *(CGVector, *CGFloat*) and /(CGVector, *CGFloat*).
>>
>> After consulting a mathematician, I believe what the lerp function really
>> wants is for its generic param to be an affine space
>> . I explored this a bit here:
>> https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b
>> 03#file-affine-swift-L16-L18
>>
>> This approach is less restrictive and more composable than the proposed
>> Arithmetic protocol, which can be viewed as a special case with the
>> following definitions:
>>
>> extension Arithmetic: AffineSpace, VectorSpace {  // not actually
>> allowed in Swift
>> typealias Displacement = Self
>> typealias Scalar = Self
>> }
>>
>> It'd be great to be able to define a lerp() which works for all
>> floating-point and integer numbers, as well as points and vectors (assuming
>> a glorious future where CGPoint and CGVector have built-in arithmetic
>> operations). But maybe the complexity of these extra protocols isn't worth
>> it for the stdlib...
>>
>
> I think, in the end, it's the _name_ that could use improvement here. As
> the doc comments say, `Arithmetic` is supposed to provide a "suitable basis
> for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
> appropriate? It would make it clear that `CGVector` is not meant to be a
> conforming type.

We want Arithmetic to be able to handle complex numbers.  Whether Scalar
would be appropriate in that case sort of depends on what the implied
field is, right?

It's true that CGPoint and CGVector have no obvious sensible
interpretation of "42", and that's unfortunate.  The problem with
protocols for algebraic structures is that there's an incredibly
complicated lattice (see figures 3.1, 3.2 in
ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
shove all of those protocols into the standard library (especially not
prematurely) but each requirement you add to a more-coarsely aggregated
protocol like Arithmetic will make it ineligible for representing some
important type.  

That said, the ability to interpret integer literals as an arbitrary
Arithmetic isn't used anywhere in the standard library, so I'd like to
consider undoing
https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
BinaryInteger.

>> *## BinaryInteger*
>>
>> I'm a little confused by the presence of init(extendingOrTruncating:) for
>> *all* binary integers. Why does it make sense to be able to write
>> UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind, sign-extension
>> only has meaning when the source and destination types are both signed.
>>
>
> Here (just IMHO), I disagree. Since any binary integer can be truncated and
> any can be right-shifted, it makes sense for `init(extendingOrTruncating:)`
> to be available for all of them. If I understand the proposal correctly,
> `Int(extendingOrTruncating: (-1 as Int8))` would give you a different
> result than `Int(extendingOrTruncating: (255 as UInt8)`.

Yes it would.  But the real justification for this operation is generic
programming with integers.  It isn't possible, today, to define:

  init(extending:T) where T.isNarrowerThan(Self)
  init(truncating:T) where T.isWiderThan(Self)

>> Although I would not be against a clamp() function in the standard library,
>> "init(clamping:)" sounds strange to me. What about calling it
>> "init(nearestTo:)"?  One could also define a FloatingPoint version 

Re: [swift-evolution] Code comments that check code validity.

2017-01-14 Thread Jay Abbott via swift-evolution
I think this would be an anti-feature , here are some reasons why:

   - If it is code you wrote as an idea for how something might be
   implemented in the future, then it should be manually tweaked/validated
   anyway when you put it back in. If things change slightly such that your
   old commented code breaks when you comment it back in this is a good thing,
   it forces you to check/amend the old code so that it functions properly in
   the updated environment that it now inhabits.
   - If it’s a significant amount of code then it really ought to be
   structured into something appropriate, like a function or a class, in which
   case it can happily live uncalled and not commented out. But it’s not a
   great practice to leave unused code lying around, unless you know it’s
   going to be used soon.
   - Commented code is often commented out specifically to make things
   compile while you tweak/break things somewhere else (i.e. commented out
   temporarily) - so of course you don’t want it to be compiled.
   - If you comment out code temporarily then it really should just mean
   temporarily, i.e. between now and your next commit to test something
   immediately. Source control means there’s no need for longer-lived
   commented out code. Unfinished code can live on a branch, old code that you
   might want to refer to or re-use later is in your source control history,
   and unused code should probably just be removed.
   - Code that is written and working and intended to be enabled later on
   should be activated by a feature-toggle (either a compile-time or a
   run-time one) rather than commented out.

​

On Sun, 15 Jan 2017 at 00:04 Amir Michail via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Jan 14, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>
>
>
> On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  wrote:
>
>
> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
>
> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:
>
>
> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
> >
> > This has been brought up on this list before. The conclusion of the
> previous thread on this topic was that there is a way to do this:
> >
> > #if false
> > // put your code here
> > #endif
> >
>
> This would not check the code for compilability within the surrounding
> code. This requires more than a syntax check.
>
>
> I can't say I've ever needed that feature; could you share a concrete use
> case?
>
>
> Consider an array of levels for a game where some levels are commented out
> for possible future use. It would be nice to have such level entries
> continue to compile as the code elsewhere evolves and yet not be included
> in the executable.
>
>
> ```
> enum Levels: Int {
>   case foo = 1, bar, baz, boo
> }
>
> var levels: [Levels] = [
>   .foo,
>   .bar,
> ]
>
> // disabled
> _ = {
>   levels += [
> .baz,
> .boo,
> // this won't compile if you add:
> // .nonExistent,
>   ]
> }
> ```
>
>
> That’s helpful thanks! I still think code comments would be nice though.
>
>
> ___
> 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] Support for assertions/preconditions that sometimes fail.

2017-01-14 Thread Saagar Jha via swift-evolution
Why not just add a // TODO or // FIXME comment?

Saagar Jha

> On Jan 14, 2017, at 4:10 PM, Amir Michail via swift-evolution 
>  wrote:
> 
> It’s quite common for an assertion/precondition that you thought should hold 
> actually does not yet there is no bug. In that case, you might want to remind 
> yourself of this fact by commenting out the assertion/precondition (instead 
> of deleting it) so that you don’t make the same mistake in the future by 
> inserting such assertions/preconditions into the code.
> 
> However, it would be nice to have explicit support for 
> assertions/preconditions that don’t always hold where there is no bug.
> 
> For example:
> 
> preconditionNotAlwaysTrue( list.isEmpty )
> 
> When your app finishes running, the IDE could show you all such 
> preconditions/assertions that you thought fail sometimes that did not fail in 
> that particular run. In that case, you might consider switching them to 
> normal preconditions/assertions provided your code has now evolved to the 
> point where they always hold.
> ___
> 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] Support for assertions/preconditions that sometimes fail.

2017-01-14 Thread Amir Michail via swift-evolution
It’s quite common for an assertion/precondition that you thought should hold 
actually does not yet there is no bug. In that case, you might want to remind 
yourself of this fact by commenting out the assertion/precondition (instead of 
deleting it) so that you don’t make the same mistake in the future by inserting 
such assertions/preconditions into the code.

However, it would be nice to have explicit support for assertions/preconditions 
that don’t always hold where there is no bug.

For example:

preconditionNotAlwaysTrue( list.isEmpty )

When your app finishes running, the IDE could show you all such 
preconditions/assertions that you thought fail sometimes that did not fail in 
that particular run. In that case, you might consider switching them to normal 
preconditions/assertions provided your code has now evolved to the point where 
they always hold.
___
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-14 Thread Dave Abrahams via swift-evolution

on Fri Jan 13 2017, Max Moiseev  wrote:

> So, in an expression `x &>> 32`, compiler assumes 32 to have type Int
> (which is the default type for the integer literals) and prefer the
> heterogeneous overload. It might not be too bad, as I showed in
> examples above, but in order to increase chances of success you might
> want to specify an explicit type context, as in `x &>> (32 as
> TypeOfX)`.

It's easy to prove that the heterogeneous overload can't have different
semantics from the homogeneous one, so there is absolutely nothing to
worry about—other than, arguably, that it could take slightly more
time to type-check.

-- 
-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-14 Thread Dave Abrahams via swift-evolution

on Sat Jan 14 2017, Xiaodi Wu  wrote:

> On Fri, Jan 13, 2017 at 7:51 PM, Xiaodi Wu 
> wrote:
>
>> Thanks, that's very helpful. Yes, my question was more directed to those
>> situations that can't be optimized away. It's good to know that the maximum
>> total cost is an and and a shift, which is what it sounded like but wasn't
>> made explicit.
>
> Oy, I misread your reply; the maximum total cost for a _masking_ shift is
> two very cheap instructions; the maximum total cost for a _smart_ shift is
> potentially higher. I know it's unrealistic, but what will we be looking at
> when it comes to this:
>
> ```
> func foo() -> UInt32 {
> return arc4random() >> arc4random()
> }
> ```

This is a shift by an unsigned quantity, so we know it's positive.  It
should optimize down to something like this:

 let _lhs = arc4random(), _rhs = arc4random()
 return _rhs > 31 ? 0 : Builtin.shiftRight(_lhs, _rhs)

> On Fri, Jan 13, 2017 at 17:25 Stephen Canon  wrote:
>>
>>> > On Jan 13, 2017, at 5:14 PM, Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>> >
>>> > [Resending to list with original message removed for length.]
>>> >
>>> > This is fantastic. Glad to see it take shape. Very neat and insightful
>>> to have trailingZeros on BinaryInteger but leadingZeros on
>>> FixedWidthInteger. A couple of questions on smart shifts: What is the
>>> performance penalty as compared to the existing operators? Beyond
>>> performance, what are the implications for migrating existing bit twiddling
>>> algorithms written in Swift 3?
>>>
>>> Hi Xiaodi —
>>>
>>> I don’t want to speak for Max and Dave, but I think I can provide some
>>> insight for your questions about shifts.
>>>
>>> First, the overwhelming majority of shifts have a compile-time-constant
>>> RHS. For these cases, there’s no performance change (except that the smart
>>> shifts may be able to optimize away the entire expression if the shift is
>>> overlarge).
>>>
>>> For smart shifts with non-constant right-hand sides, the compiler will
>>> frequently still be able to prove that the shift count is always positive
>>> or negative and less than word size (this handles a lot of the most common
>>> cases like normalizing an integer, reading from a bitstream, or shifting
>>> words of a bignum); again there’s no performance penalty.
>>>
>>> In the remaining cases where the compiler cannot bound the right-hand
>>> side, there will be some branches present; there may be a few regressions
>>> from these cases, but I expect most to be small (and the code
>>> simplifications are well worth it).  Users can always use the masking
>>> shifts, which lower to single instructions for 32b and 64b integers types
>>> on Intel and arm64, and which are at worst an and and a shift (two very
>>> cheap instructions) on other architectures.
>>>
>>> Basically, I expect there to be no perf impact for almost all code, and
>>> that the perf impact is relatively easily mitigated when it does occur.
>>> This is an easy tradeoff for fully-defined and sensible operator behavior.
>>>
>>> – Steve
>>
>>
> ___
> 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] Code comments that check code validity.

2017-01-14 Thread Amir Michail via swift-evolution

> On Jan 14, 2017, at 6:56 PM, Xiaodi Wu  wrote:
> 
> 
> 
> On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  > wrote:
> 
>> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu > > wrote:
>> 
>> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail > > wrote:
>> 
>> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu > > > wrote:
>> >
>> > This has been brought up on this list before. The conclusion of the 
>> > previous thread on this topic was that there is a way to do this:
>> >
>> > #if false
>> > // put your code here
>> > #endif
>> >
>> 
>> This would not check the code for compilability within the surrounding code. 
>> This requires more than a syntax check.
>> 
>> I can't say I've ever needed that feature; could you share a concrete use 
>> case?
>> 
> 
> Consider an array of levels for a game where some levels are commented out 
> for possible future use. It would be nice to have such level entries continue 
> to compile as the code elsewhere evolves and yet not be included in the 
> executable.
> 
> ```
> enum Levels: Int {
>   case foo = 1, bar, baz, boo
> }
> 
> var levels: [Levels] = [
>   .foo,
>   .bar,
> ]
> 
> // disabled
> _ = {
>   levels += [
> .baz,
> .boo,
> // this won't compile if you add:
> // .nonExistent,
>   ]
> }
> ```

That’s helpful thanks! I still think code comments would be nice though.


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


Re: [swift-evolution] Code comments that check code validity.

2017-01-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  wrote:

>
> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
>
> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:
>
>>
>> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
>> >
>> > This has been brought up on this list before. The conclusion of the
>> previous thread on this topic was that there is a way to do this:
>> >
>> > #if false
>> > // put your code here
>> > #endif
>> >
>>
>> This would not check the code for compilability within the surrounding
>> code. This requires more than a syntax check.
>
>
> I can't say I've ever needed that feature; could you share a concrete use
> case?
>
>
> Consider an array of levels for a game where some levels are commented out
> for possible future use. It would be nice to have such level entries
> continue to compile as the code elsewhere evolves and yet not be included
> in the executable.
>

```
enum Levels: Int {
  case foo = 1, bar, baz, boo
}

var levels: [Levels] = [
  .foo,
  .bar,
]

// disabled
_ = {
  levels += [
.baz,
.boo,
// this won't compile if you add:
// .nonExistent,
  ]
}
```
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Code comments that check code validity.

2017-01-14 Thread Amir Michail via swift-evolution

> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
> 
> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  > wrote:
> 
> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  > > wrote:
> >
> > This has been brought up on this list before. The conclusion of the 
> > previous thread on this topic was that there is a way to do this:
> >
> > #if false
> > // put your code here
> > #endif
> >
> 
> This would not check the code for compilability within the surrounding code. 
> This requires more than a syntax check.
> 
> I can't say I've ever needed that feature; could you share a concrete use 
> case?
> 

Consider an array of levels for a game where some levels are commented out for 
possible future use. It would be nice to have such level entries continue to 
compile as the code elsewhere evolves and yet not be included in the executable.

> In any case, if you put code in a function that's not exported and never 
> invoked, I believe you would achieve the desired effect. Within the body of a 
> function, you could do so in a closure.
> 
> ```
> func foo() {
>   // code you want to run
>   _ = {
> // code you don't intend to run
>   }
>   // more code you want to run
> }
> ```
> 
> > It does not allow you to comment out fragments of a single statement, but 
> > the incremental value of devoting time to additionally support that is, it 
> > would seem, low.
> >
> > On Sat, Jan 14, 2017 at 17:18 Amir Michail via swift-evolution 
> > > wrote:
> > The code in a “code comment" must compile (not just be syntactically 
> > correct) yet must not have any effect on the resulting executable.
> >
> > For example, commented entries in an array would be checked for 
> > compilability but would not be included in the executable.
> >
> > Such “code comments" would allow you to have code/data that is currently 
> > unused but is constantly checked to be valid just in case you want to use 
> > it in the future.
> >
> > ___
> > 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] Code comments that check code validity.

2017-01-14 Thread Xiaodi Wu via swift-evolution
This has been brought up on this list before. The conclusion of the
previous thread on this topic was that there is a way to do this:

#if false
// put your code here
#endif

It does not allow you to comment out fragments of a single statement, but
the incremental value of devoting time to additionally support that is, it
would seem, low.

On Sat, Jan 14, 2017 at 17:18 Amir Michail via swift-evolution <
swift-evolution@swift.org> wrote:

> The code in a “code comment" must compile (not just be syntactically
> correct) yet must not have any effect on the resulting executable.
>
> For example, commented entries in an array would be checked for
> compilability but would not be included in the executable.
>
> Such “code comments" would allow you to have code/data that is currently
> unused but is constantly checked to be valid just in case you want to use
> it in the future.
>
> ___
> 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] Code comments that check code validity.

2017-01-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:

>
> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
> >
> > This has been brought up on this list before. The conclusion of the
> previous thread on this topic was that there is a way to do this:
> >
> > #if false
> > // put your code here
> > #endif
> >
>
> This would not check the code for compilability within the surrounding
> code. This requires more than a syntax check.


I can't say I've ever needed that feature; could you share a concrete use
case?

In any case, if you put code in a function that's not exported and never
invoked, I believe you would achieve the desired effect. Within the body of
a function, you could do so in a closure.

```
func foo() {
  // code you want to run
  _ = {
// code you don't intend to run
  }
  // more code you want to run
}
```

> It does not allow you to comment out fragments of a single statement, but
> the incremental value of devoting time to additionally support that is, it
> would seem, low.
> >
> > On Sat, Jan 14, 2017 at 17:18 Amir Michail via swift-evolution <
> swift-evolution@swift.org> wrote:
> > The code in a “code comment" must compile (not just be syntactically
> correct) yet must not have any effect on the resulting executable.
> >
> > For example, commented entries in an array would be checked for
> compilability but would not be included in the executable.
> >
> > Such “code comments" would allow you to have code/data that is currently
> unused but is constantly checked to be valid just in case you want to use
> it in the future.
> >
> > ___
> > 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] Throwing Subscripts (was: Generic Subscripts)

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

Just a request that posters update the subject line when the topic of
discussion changes.

Thanks,
Dave

on Wed Jan 11 2017, Erica Sadun  wrote:

>> On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution
>>  wrote:
>> 
>> On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution
>> 
>> >
>> wrote:
 On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution
 >
 wrote:
 
 [Forgot to CC swift-evolution the first time]
 
 When this came up last, it was seen as more so a bug in the
 current implementation, rather than an explicit choice. There's no
 need for a proposal, just a JIRA:
 https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
 
>>> 
>>> It’s a nontrivial new user-facing feature with new syntax in the
>>> language, so it’ll need a proposal. ‘twould be good for the
>>> proposal to link to the JIRA ticket.
>>> 
>>> I’ve only heard positive reactions toward this feature, and it’s
>>> something that the standard library could make good use of.
>> 
>> +1, this would be clearly great to happen.
>> 
>> -Chris
>
> I apologize for adding to this topic rather than starting a new one,
> but I figure people interested in subscripts would be more likely to
> see my question:
>
> Is there a good reason subscripts cannot throw? Right now you can
> create a [safe: index] subscript to return an optional but you can't
> create one that returns an unwrapped value or throws.
>
> Thanks, -- E
>
> ___
> 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] Generic Subscripts

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

on Fri Jan 13 2017, John McCall  wrote:

> I'm also not sure we'd ever want the element type to be inferred from
> context like this.  Generic subscripts as I see it are about being
> generic over *indexes*, not somehow about presenting a polymorphic
> value.

Actually I *would* want to be able to do that, though I admit it's the
1% case (or less).

-- 
-Dave

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


Re: [swift-evolution] Code comments that check code validity.

2017-01-14 Thread Amir Michail via swift-evolution

> On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
> 
> This has been brought up on this list before. The conclusion of the previous 
> thread on this topic was that there is a way to do this:
> 
> #if false
> // put your code here
> #endif
> 

This would not check the code for compilability within the surrounding code. 
This requires more than a syntax check.

> It does not allow you to comment out fragments of a single statement, but the 
> incremental value of devoting time to additionally support that is, it would 
> seem, low.
> 
> On Sat, Jan 14, 2017 at 17:18 Amir Michail via swift-evolution 
>  wrote:
> The code in a “code comment" must compile (not just be syntactically correct) 
> yet must not have any effect on the resulting executable.
> 
> For example, commented entries in an array would be checked for compilability 
> but would not be included in the executable.
> 
> Such “code comments" would allow you to have code/data that is currently 
> unused but is constantly checked to be valid just in case you want to use it 
> in the future.
> 
> ___
> 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] Code comments that check code validity.

2017-01-14 Thread Amir Michail via swift-evolution
The code in a “code comment" must compile (not just be syntactically correct) 
yet must not have any effect on the resulting executable.

For example, commented entries in an array would be checked for compilability 
but would not be included in the executable.

Such “code comments" would allow you to have code/data that is currently unused 
but is constantly checked to be valid just in case you want to use it in the 
future.

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


Re: [swift-evolution] Consolidate Code for Each Case in Enum

2017-01-14 Thread Tim Shadel via swift-evolution
With everything quiet on this discussion since my last update removing 
defaults, I've gone ahead and submitted a pull request 
(https://github.com/apple/swift-evolution/pull/585 
) with the latest draft. I'm 
certainly happy to still update it if anything arises.

Thanks to all who helped out!

—Tim

> On Jan 13, 2017, at 12:23 AM, Rien  wrote:
> 
> +1
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Swiftrien
> Project: http://swiftfire.nl
> 
> 
> 
> 
>> On 13 Jan 2017, at 03:01, Tim Shadel via swift-evolution 
>>  wrote:
>> 
>> Fantastic points, all. Let me reply to a few.
>> 
>> First, the odd situations you mentioned with the defaults were spot on. I 
>> had seen them, and thought a bit about it, but having you write it out in 
>> code made it obvious that they're pretty harmful. I've removed defaults 
>> entirely (see the updated Alternatives and Errors sections). This is 
>> actually a really good indicator of whether you should use this syntax or 
>> not. If you'll save a noticeable amount of space by using a default, then 
>> this isn't the syntax for your situation.
>> 
>> To make that more obvious, I've added a Mixed Use Example 
>> (https://gist.github.com/timshadel/5a5a8e085a6fd591483a933e603c2562#mixed-use-example)
>>  showing how simple it is to use the existing syntax when you have a default 
>> and a small number of exceptions, alongside the case block syntax for things 
>> that are unique for each case. So, to summarize, I think that forcing the 
>> additional code for each case is a good thing so that this syntax remains 
>> the exception used when needed, instead of becoming the rule.
>> 
>> Now to your other points. The intent isn't to alter the amount of code 
>> required to accomplish the task (code *complexity*), but to simplify 
>> *maintenance and understanding* by allowing you to organize the code either 
>> by property or by case (according to the merits of the code and your 
>> judgement). Indeed, I try to highlight in the proposal that this usually 
>> _increases_ code verbosity slightly in favor of the readability gained by 
>> shifting the code layout.
>> 
>> Finally, to your point about attaching properties to values (also echoed in 
>> David's musings about tagged unions vs Swift enums), it is different, but 
>> I'm not sure of a cleaner way to group all the code related to a single case 
>> for complex enums. In another light, no other type in Swift makes such heavy 
>> use of `switch` statements as a mechanism to organize code, and so this 
>> starts to make enum code look more like the rest of the code you find in 
>> Swift projects, which could be a good thing for long-term readability.
>> 
>> 
>>> On Jan 11, 2017, at 9:22 AM, Tony Allevato  wrote:
>>> 
>>> I'll summarize my thoughts for now, after thinking about it for a bit 
>>> longer:
>>> 
>>> Plusses:
>>> + In some cases it's nicer to have the ability to group functionality at 
>>> each case rather than spread across methods lower in the type definition. 
>>> I've written enums that were like state machines where being able to have 
>>> the next state transition and other associated data grouped with the case 
>>> would have made the code a bit cleaner, IMO.
>>> + This is the cleanest syntax I've seen proposed for this idea.
>>> 
>>> Things that worry me:
>>> – It's a new way to express the same idea without necessarily *simplifying* 
>>> it in terms of code complexity.
>>> – It adds a fair amount of complexity to the compiler, to build the 
>>> implicit self-switch and merge the implementations for each partial 
>>> property/function.
>>> – It would be the first time, I believe, in Swift where properties/method 
>>> implementations are attached to *values* rather than just to the *type*. 
>>> That's quite a departure from the way we model these concepts.
>>> – The use of the type-defined implementation as the default when a 
>>> case-defined implementation is omitted can lead to some bizarre 
>>> combinations, which I think need to be addressed in the proposal. Consider 
>>> this:
>>> 
>>> ```
>>> enum Foo {
>>>  var description: String {
>>>switch self {
>>>case .bar: return "bar"
>>>case .baz: return "baz"
>>>default: return ""
>>>  }
>>> 
>>>  case bar
>>>  case baz
>>>  case quux {
>>>var description: String { return "quux" }
>>>  }
>>> }
>>> ```
>>> 
>>> Should the user be able to omit the `default` case because everything is 
>>> exhaustively covered without it? *Conceptually* yes, but that would require 
>>> the compiler to analyze the switch statement inside `description` and 
>>> understand that, which is probably not feasible for anything but the 
>>> simplest examples (and perhaps not even for those). Otherwise, it would 
>>> presumably transform the implementation to this:
>>> 
>>> ```
>>>  var 

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

2017-01-14 Thread Stephen Canon via swift-evolution

> On Jan 14, 2017, at 11:18 AM, Xiaodi Wu  wrote:
> 
> On Fri, Jan 13, 2017 at 7:51 PM, Xiaodi Wu  > wrote:
> Thanks, that's very helpful. Yes, my question was more directed to those 
> situations that can't be optimized away. It's good to know that the maximum 
> total cost is an and and a shift, which is what it sounded like but wasn't 
> made explicit.
> 
> Oy, I misread your reply; the maximum total cost for a _masking_ shift is two 
> very cheap instructions; the maximum total cost for a _smart_ shift is 
> potentially higher. I know it's unrealistic, but what will we be looking at 
> when it comes to this:
> 
> ```
> func foo() -> UInt32 {
> return arc4random() >> arc4random()
> }
> ```

This specific example generates a compare, shift, and conditional move of zero. 
Still very cheap (a branch would arguably be even better, since the result is 
almost always zero in this particular case).

If the RHS is not unsigned, so that it might also be negative, the very rare 
absolute worst case codegen for basic integer types should be something like 
[add, compare, negate, 2xshift, 2xselect].

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


Re: [swift-evolution] Generic Subscripts

2017-01-14 Thread Gwendal Roué via swift-evolution
> Le 14 janv. 2017 à 18:45, Anton Zhilin  a écrit :
> 
> I’m not sure, but I think that in this case the specific type of these values 
> is determined at runtime.
> Then a safe approach would be separate string: String?, bool: Bool?, int: 
> Int? computed properties, as it’s done in JSON parsers.
> 
> if let bookCount = row.value(named: "bookCount").int {
> ...
> }
> if let bookCount = row["bookCount"].int {
> ...
> }
> let bookCount = row.int ("bookCount")!   // crash if 
> database is corrupt
> Additionally, this is an overall bad example of generics. Fields of database 
> tables can only map to a limited set of static types in Swift, which are 
> supported by database adapter
> 
Thanks for the compliment! I disagree, of course.

App developers may need to fetch basic database data types, obviously, but also 
RawRepresentable types based on those types, dates, date components, uuids, 
serialized JSON, and generally speaking a large and extensible set of 
serializable types.

This is, I believe, a very good usage of return type genericity, as well as an 
excellent opportunity for the open/closed principle 
(https://en.wikipedia.org/wiki/Open/closed_principle 
).

Gwendal

> 2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution 
> >:
> 
> As the developer of a Swift database library, I'd like to offer a better API 
> than the following:
> 
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
> 
> Instead, I wish I could offer GRDB.swift would let its users write:
> 
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
> 
> And this requires genericity on return type.
> 
> Gwendal
> 
> 
> ___
> 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] Generic Subscripts

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


Sent from my iPad

> On Jan 14, 2017, at 12:17 PM, Shawn Erickson via swift-evolution 
>  wrote:
> 
> I have a throwing style data marshaling layer that uses throwing and return 
> type inference to make the code clean and validation automatic with the 
> optional ability to return default values if error or missing value, etc. 
> This is for validating data coming from external sources into our app. Having 
> generic return type and throwing subscripts would help make this code better 
> for clients IMHO.
> 
> class Data {
> let number: Int
> let name: String
> }
> 
> 
> data.number = try helper.value(forKey: "baz")
> data.name = try helper.value(forKey: "foo", otherwise: "bar")
> 
> 
>  or ideally something like 
> 
> 
> data.number = try helper["baz"]
> data.name = try helper["foo", otherwise: "bar"]
> 
> 

This is exactly the kind of library I was mentioning.  There is a lot of demand 
for the ability to write these kinds of libraries for various different 
purposes.

> -Shawn
> 
> 
> On Sat, Jan 14, 2017 at 9:45 AM Anton Zhilin via swift-evolution 
>  wrote:
> I’m not sure, but I think that in this case the specific type of these values 
> is determined at runtime.
> Then a safe approach would be separate string: String?, bool: Bool?, int: 
> Int? computed properties, as it’s done in JSON parsers.
> 
> 
> 
> if let bookCount = row.value(named: "bookCount").int {
> 
> ...
> 
> }
> 
> if let bookCount = row["bookCount"].int {
> 
> ...
> 
> }
> 
> let bookCount = row.int("bookCount")!   // crash if database is corrupt
> 
> Additionally, this is an overall bad example of generics. Fields of database 
> tables can only map to a limited set of static types in Swift, which are 
> supported by database adapter.
> 
> 
> 
> 2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution 
> :
> 
> 
> 
> This is a consequence of your vision of subscript. If interesting, it is also 
> limiting for no real purpose.
> 
> As the developer of a Swift database library, I'd like to offer a better API 
> than the following:
> 
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
> 
> Instead, I wish I could offer GRDB.swift would let its users write:
> 
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
> 
> And this requires genericity on return type.
> 
> Gwendal
> 
> 
> ___
> 
> 
> 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] Generic Subscripts

2017-01-14 Thread Rien via swift-evolution

> On 14 Jan 2017, at 18:45, Anton Zhilin via swift-evolution 
>  wrote:
> 
> I’m not sure, but I think that in this case the specific type of these values 
> is determined at runtime.
> Then a safe approach would be separate string: String?, bool: Bool?, int: 
> Int? computed properties, as it’s done in JSON parsers.

Yup. This is what I do:

var json = VJson()
var name: String?

json[“books”][1][“title”] &= “THHGTTG” 

and the reverse

name &= json[“books”][1][“title"]

The overloaded operator ‘&=‘ takes care of the types. (‘=‘ cannot be overloaded)



> 
> if let bookCount = row.value(named: "bookCount").int {
> ...
> }
> if let bookCount = row["bookCount"].int {
> ...
> }
> let bookCount = 
> row.int
> ("bookCount")!   // crash if database is corrupt
> 
> Additionally, this is an overall bad example of generics. Fields of database 
> tables can only map to a limited set of static types in Swift, which are 
> supported by database adapter.
> 
> 2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution 
> :
> 
> 
> 
> This is a consequence of your vision of subscript. If interesting, it is also 
> limiting for no real purpose.
> 
> As the developer of a Swift database library, I'd like to offer a better API 
> than the following:
> 
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
> 
> Instead, I wish I could offer GRDB.swift would let its users write:
> 
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
> 
> And this requires genericity on return type.
> 
> Gwendal
> 
> 
> ___
> 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

Regards,
Rien

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




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


Re: [swift-evolution] Generic Subscripts

2017-01-14 Thread Shawn Erickson via swift-evolution
I have a throwing style data marshaling layer that uses throwing and return
type inference to make the code clean and validation automatic with the
optional ability to return default values if error or missing value, etc.
This is for validating data coming from external sources into our app.
Having generic return type and throwing subscripts would help make this
code better for clients IMHO.

class Data {
let number: Int
let name: String
}


data.number = try helper.value(forKey: "baz")
data.name = try helper.value(forKey: "foo", otherwise: "bar")


 or ideally something like 


data.number = try helper["baz"]
data.name = try helper["foo", otherwise: "bar"]


-Shawn


On Sat, Jan 14, 2017 at 9:45 AM Anton Zhilin via swift-evolution <
swift-evolution@swift.org> wrote:

I’m not sure, but I think that in this case the specific type of these
values is determined at runtime.
Then a safe approach would be separate string: String?, bool: Bool?, int:
Int? computed properties, as it’s done in JSON parsers.


if let bookCount = row.value(named: "bookCount").int {

...

}

if let bookCount = row["bookCount"].int {

...

}

let bookCount = row.int("bookCount")!   // crash if database is corrupt

Additionally, this is an overall bad example of generics. Fields of
database tables can only map to a limited set of static types in Swift,
which are supported by database adapter.


2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution <
swift-evolution@swift.org>:


This is a consequence of your vision of subscript. If interesting, it is
also limiting for no real purpose.

As the developer of a Swift database library, I'd like to offer a better
API than the following:

// Current state of affairs
let name: String = row.value(named: "name")
let bookCount: Int = row.value(named: "bookCount")
let hasBooks: Bool = row.value(named: "bookCount")

Instead, I wish I could offer GRDB.swift would let its users write:

// With improved subscripts
let name: String = row["name"]
let bookCount: Int = row["bookCount"]
let hasBooks: Bool = row["bookCount"]

And this requires genericity on return type.

Gwendal


___


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] Generic Subscripts

2017-01-14 Thread Anton Zhilin via swift-evolution
I’m not sure, but I think that in this case the specific type of these
values is determined at runtime.
Then a safe approach would be separate string: String?, bool: Bool?, int:
Int? computed properties, as it’s done in JSON parsers.

if let bookCount = row.value(named: "bookCount").int {
...
}
if let bookCount = row["bookCount"].int {
...
}
let bookCount = row.int("bookCount")!   // crash if database is corrupt

Additionally, this is an overall bad example of generics. Fields of
database tables can only map to a limited set of static types in Swift,
which are supported by database adapter.

2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution <
swift-evolution@swift.org>:

This is a consequence of your vision of subscript. If interesting, it is
> also limiting for no real purpose.
>
> As the developer of a Swift database library, I'd like to offer a better
> API than the following:
>
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
>
> Instead, I wish I could offer GRDB.swift would let its users write:
>
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
>
> And this requires genericity on return type.
>
> Gwendal
>
>
> ___
> 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] [Proposal] Allow scoped properties from within computed properties

2017-01-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 9:36 AM, Joseph Newton  wrote:

> Thank you for your responses Xiaodi and David,
>
> I believe you can do this using didSet without the `_bar`:
>> class Foo {
>> public var bar: String? {
>
> didSet {
>> if (bar?.characters.count ?? 0) < 100 {
>> bar = nil
>> }
>> }
>> }
>> }
>
>
> Yes, although this is a perfectly valid way of implementing this, I'm not
> a big fan of implementing this functionality in this way. Particularly, I
> don't like the concept of validating data after setting it, and then
> re-setting the property if the validation failed. I would much rather
> implement it in a manner where it's conditionally set depending on
> validation.
>
> It's an interesting idea, for sure. Because of the persistent storage
>> required for `_bar`, I *think* one way to look at what you're proposing
>> is essentially as a way to allow for a variable to be declared publicly
>> as one type, be implemented as another (anonymous, in this case) type under
>> the hood, and to specify a mechanism for automatically converting between
>> the two types.
>
>
> Essentially, yes. The programmer would have the option of using these
> nested properties to be able to add custom storage or functionality to any
> computed property that they please.
>
> (That said, there is a recurrent theme on this list where people ask for
>> new support for encapsulating members from visibility in ever smaller
>> scopes. I continue to be not in favor of the new `private`, but even
>> allowing its existence, providing all the permutations of
>> type/file/extension visibility is (afaict) and should continue to be (imo)
>> a non-goal. The distinction between public and internal not only avoids
>> pollution in your autocomplete list but also provides important safety
>> wins, and I think those gains are increasingly limited the finer we dice
>> these access levels.)
>
>
> I'm not sure that I quite understand what you mean by this. Would you mind
> elaborating?
>

See below.


>  I get that your proposal allows you to write one fewer declaration in
>> the case of an ad-hoc behavior than SE-0030 would. That is, in the case of
>> SE-0030, you'd have to declare both a behavior and a member that uses it;
>> in your case, you could declare just the member and implement the behavior
>> there. However, I think I'd want to see some concrete use cases that are
>> better served by this proposal than by SE-0030, which is the more general
>> solution as far as I can tell. In the two use cases you've mentioned, one
>> is served by `didSet`, and the other (`synchronized`) is a reusable
>> behavior for which SE-0030 offers the more elegant solution.
>
>
> Here are some additional uses cases for this proposal:
>
> *Implementing Objective-C's "__null_resettable"*
>
> class Foo {
> var bar: UIColor! {
> var _bar: UIColor = .clear
>
> get { _return _bar }
> set { _bar = newValue ?? .clear }
> }
> }
>

In this use case, your proposal differs from what's currently possible only
in that `_bar` (presumably, after you write `private` in front of it, for
consistency with current rules about default access levels) would be
invisible even inside `Foo`. As I wrote to you above, avoiding "pollution"
within ever smaller scopes [in this case, the scope inside `Foo`] is
(AFAICT) and should be (IMO) a non-goal. To convince me that this use case
is worth the engineering effort and complexity of a new syntax, you'd also
have to convince me that having `_bar` visible within the entire scope of
`Foo` has practical and not merely theoretical footgun potential or some
other negative impact beyond the fact that autocomplete will show a member
you'd rather not see.

_Even if_ I were to buy that argument, I think there is a more general
solution that covers your use case. A few months earlier on this list,
several people discussed the possibility of same-module extensions allowing
stored properties, to very positive reception. There are numerous use cases
for that feature, but such a feature would also allow you to isolate `_bar`
and `bar` in its own extension, a common Swift idiom. It would also allow
you to group this implementation in the same extension with arbitrary
functions that need to see `_bar` (such as your `init(_:)` example below)
without exposing `_bar` to other initializer and methods that don't need to
manipulate it. This would be both more flexible and more fine-grained than
possible with your own proposal, and if I were to buy your argument that
`_bar` being visible where it's not needed is suboptimal, this would be the
optimal solution.

*Implementing a stack interface*
>
> class Foo {
> var currentItem: T? {
> var storage = [T]()
>
> get { return storage.last }
> set {
> if let newValue = newValue {
> storage.append(newValue)
> }
> else {
>

Re: [swift-evolution] Generic Subscripts

2017-01-14 Thread Shawn Erickson via swift-evolution
I have very similar needs as well to allow for things to be generic on
return type.

On Sat, Jan 14, 2017 at 5:50 AM Gwendal Roué via swift-evolution <
swift-evolution@swift.org> wrote:

> Where generic subscripts are concerned, there are a couple of different
> things to express:
> - Generic parameter  (I can understand various co-ordinates for the data)
> - Generic return type (I can construct your preferred representation of
> the data)
> - Generic setter type (I can set the data using various compatible types):
>
>
> I think all of these should be expressed with a single generic signature
> on the subscript itself. The element type passed to the setter and returned
> from the getter should be the same IMO, otherwise it’s not clear how it
> will work.
>
>
> Yes.  It's quite important that any particular subscript reference is
> still a single consistent entity, even if generic; we would not want, say,
> a read-modify-write access to be able to somehow invoke the getter and
> setter at different generic arguments, or to traffic in different element
> types.
>
> I'm also not sure we'd ever want the element type to be inferred from
> context like this.  Generic subscripts as I see it are about being generic
> over *indexes*, not somehow about presenting a polymorphic value.
>
>
> This is a consequence of your vision of subscript. If interesting, it is
> also limiting for no real purpose.
>
> As the developer of a Swift database library, I'd like to offer a better
> API than the following:
>
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
>
> Instead, I wish I could offer GRDB.swift would let its users write:
>
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
>
> And this requires genericity on return type.
>
> Gwendal
>
> ___
>
> 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-14 Thread Xiaodi Wu via swift-evolution
On Sat, Jan 14, 2017 at 1:32 AM, Jacob Bandes-Storch via swift-evolution <
swift-evolution@swift.org> wrote:

> Great work, all. I'm not sure I ever commented on SE-0104, so I've read
> through this one more carefully. Here are some things that came to mind:
>
> *## Arithmetic*
>
> Why are ExpressibleByIntegerLiteral and init?(exactly:)
> required? I could understand needing access to 0, but this could be
> provided by a static property or nullary initializer. It doesn't seem like
> all types supporting arithmetic operations would necessarily be convertible
> from an arbitrary binary integer.
>
>
> I tried to evaluate the Arithmetic protocol by considering what it means
> for higher-dimensional types such as CGPoint and CGVector. My use case was
> a linear interpolation function:
>
> func lerp(from a: T, to b: T, by ratio: T) -> T {
> return a + (b - a) * ratio
> }
>
> If I've read the proposal correctly, this definition works for integer and
> floating-point values. But we can't make it work properly for CGVector (or,
> perhaps less mathematically correct but more familiar, CGPoint). It's okay
> to define +(CGVector, CGVector) and -(CGVector, CGVector), but *(CGVector,
> CGVector) and /(CGVector, CGVector) don't make much sense. What we really
> want is *(CGVector, *CGFloat*) and /(CGVector, *CGFloat*).
>
> After consulting a mathematician, I believe what the lerp function really
> wants is for its generic param to be an affine space
> . I explored this a bit here:
> https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b
> 03#file-affine-swift-L16-L18
>
> This approach is less restrictive and more composable than the proposed
> Arithmetic protocol, which can be viewed as a special case with the
> following definitions:
>
> extension Arithmetic: AffineSpace, VectorSpace {  // not actually
> allowed in Swift
> typealias Displacement = Self
> typealias Scalar = Self
> }
>
> It'd be great to be able to define a lerp() which works for all
> floating-point and integer numbers, as well as points and vectors (assuming
> a glorious future where CGPoint and CGVector have built-in arithmetic
> operations). But maybe the complexity of these extra protocols isn't worth
> it for the stdlib...
>

I think, in the end, it's the _name_ that could use improvement here. As
the doc comments say, `Arithmetic` is supposed to provide a "suitable basis
for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
appropriate? It would make it clear that `CGVector` is not meant to be a
conforming type.


> *## BinaryInteger*
>
> I'm a little confused by the presence of init(extendingOrTruncating:) for
> *all* binary integers. Why does it make sense to be able to write
> UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind, sign-extension
> only has meaning when the source and destination types are both signed.
>

Here (just IMHO), I disagree. Since any binary integer can be truncated and
any can be right-shifted, it makes sense for `init(extendingOrTruncating:)`
to be available for all of them. If I understand the proposal correctly,
`Int(extendingOrTruncating: (-1 as Int8))` would give you a different
result than `Int(extendingOrTruncating: (255 as UInt8)`.

Although I would not be against a clamp() function in the standard library,
> "init(clamping:)" sounds strange to me. What about calling it
> "init(nearestTo:)"?  One could also define a FloatingPoint version of
> init(nearestTo:), i.e. lround(). For maximum annoyance and explicitness,
> you could even rename the existing init(_:) to init(truncating:) to make it
> clear that truncation, not regular rounding, occurs when converting from
> floating-point.
>

I would disagree with that as well; the existing `init(_:)` truncates the
fractional part but errors if that value is outside the representable
range, while the word "truncating" makes it sound like something is done to
make any possible source value give you a destination value (a la
"extendingOrTruncating" for integers).

Meanwhile, "nearest to" is problematic for me because either 127 and 129 is
"nearest to" 128, and neither integer is "nearest to" 500, yet
`Int8(clamping: 128)` and `Int8(clamping: 500)` both give you 127. This
operation is very different from lround() for floating point, which in
Swift is `rounded(.toNearestOrAwayFromZero)` (or just `rounded()`).

In both these cases, I think it's important to use spellings that
distinguish doing things to the fractional part of floating point values
and doing things to the binary representation of integer values. I think
there's great value in using the term "clamp", which is very different from
"nearest"; and in using an unlabeled `init(_:)` for initializing from FP
values, which is most similar to the unlabeled `init(_:)` for initializing
from integer values, as opposed to your suggested `init(truncating:)` which
connotes some similarity to 

Re: [swift-evolution] [Proposal] Allow scoped properties from within computed properties

2017-01-14 Thread Joseph Newton via swift-evolution
Thank you for your responses Xiaodi and David,

I believe you can do this using didSet without the `_bar`:
> class Foo {
> public var bar: String? {

didSet {
> if (bar?.characters.count ?? 0) < 100 {
> bar = nil
> }
> }
> }
> }


Yes, although this is a perfectly valid way of implementing this, I'm not a
big fan of implementing this functionality in this way. Particularly, I
don't like the concept of validating data after setting it, and then
re-setting the property if the validation failed. I would much rather
implement it in a manner where it's conditionally set depending on
validation.

It's an interesting idea, for sure. Because of the persistent storage
> required for `_bar`, I *think* one way to look at what you're proposing
> is essentially as a way to allow for a variable to be declared publicly
> as one type, be implemented as another (anonymous, in this case) type under
> the hood, and to specify a mechanism for automatically converting between
> the two types.


Essentially, yes. The programmer would have the option of using these
nested properties to be able to add custom storage or functionality to any
computed property that they please.

(That said, there is a recurrent theme on this list where people ask for
> new support for encapsulating members from visibility in ever smaller
> scopes. I continue to be not in favor of the new `private`, but even
> allowing its existence, providing all the permutations of
> type/file/extension visibility is (afaict) and should continue to be (imo)
> a non-goal. The distinction between public and internal not only avoids
> pollution in your autocomplete list but also provides important safety
> wins, and I think those gains are increasingly limited the finer we dice
> these access levels.)


I'm not sure that I quite understand what you mean by this. Would you mind
elaborating?

 I get that your proposal allows you to write one fewer declaration in the
> case of an ad-hoc behavior than SE-0030 would. That is, in the case of
> SE-0030, you'd have to declare both a behavior and a member that uses it;
> in your case, you could declare just the member and implement the behavior
> there. However, I think I'd want to see some concrete use cases that are
> better served by this proposal than by SE-0030, which is the more general
> solution as far as I can tell. In the two use cases you've mentioned, one
> is served by `didSet`, and the other (`synchronized`) is a reusable
> behavior for which SE-0030 offers the more elegant solution.


Here are some additional uses cases for this proposal:

*Implementing Objective-C's "__null_resettable"*

class Foo {
var bar: UIColor! {
var _bar: UIColor = .clear

get { _return _bar }
set { _bar = newValue ?? .clear }
}
}

*Implementing a stack interface*

class Foo {
var currentItem: T? {
var storage = [T]()

get { return storage.last }
set {
if let newValue = newValue {
storage.append(newValue)
}
else {
storage.removeLast()
}
}
}
}

*Validation before changing (for performance)*

class SessionManager {
var session: Session {
var _session: Session

get { return _session }
set {
if newValue != _session {
// expensive teardown code for the old session

_session = newValue

// expensive setup code for the new session
}
}
}
}

Lastly, I've been doing some additional thinking and I think that it would
be beneficial to also setting values for these nested properties inside of
*init* methods. For example, I work with C APIs a great deal and create
Swift/ObjC wrappers for them a lot, I have a case where I provide an
implementation as follows:

class Wrapper {
private var _unmanaged: UnsafePointer
var text: String {
return String(cString: _unmanaged)
}

fileprivate init(_ unmanaged: UnsafePointer) {
_unamanged = unmanaged
}
}

It's implemented in this manner because the C APIs may change the
characters pointed to by *_unmanaged* before the *text* property is
accessed. With this proposal, this code could be implemented as follows:

class Wrapper {
var text: String {
private var unmanaged: UnsafePointer

get {
return String(cString: unmanaged)
}
}

fileprivate init(_ unmanaged: UnsafePointer) {
self.text.unmanaged = unmanaged
}
}

On Fri, Jan 13, 2017 at 4:01 PM, Xiaodi Wu  wrote:

> (Forward to the list if your early replied was intended to be sent there.)
>
>
> On Fri, Jan 13, 2017 at 1:58 PM, Joseph Newton  wrote:
>
>> I believe that you're referring to SE-0030 Property Behaviors
>> ,
>> correct?

Re: [swift-evolution] Generic Subscripts

2017-01-14 Thread Goffredo Marocchi via swift-evolution

Sent from my iPhone

> On 14 Jan 2017, at 13:50, Gwendal Roué via swift-evolution 
>  wrote:
> 
 Where generic subscripts are concerned, there are a couple of different 
 things to express:
 - Generic parameter  (I can understand various co-ordinates for the data)
 - Generic return type (I can construct your preferred representation of 
 the data)
 - Generic setter type (I can set the data using various compatible types):
>>> 
>>> I think all of these should be expressed with a single generic signature on 
>>> the subscript itself. The element type passed to the setter and returned 
>>> from the getter should be the same IMO, otherwise it’s not clear how it 
>>> will work.
>> 
>> Yes.  It's quite important that any particular subscript reference is still 
>> a single consistent entity, even if generic; we would not want, say, a 
>> read-modify-write access to be able to somehow invoke the getter and setter 
>> at different generic arguments, or to traffic in different element types.
>> 
>> I'm also not sure we'd ever want the element type to be inferred from 
>> context like this.  Generic subscripts as I see it are about being generic 
>> over *indexes*, not somehow about presenting a polymorphic value.
> 
> This is a consequence of your vision of subscript. If interesting, it is also 
> limiting for no real purpose.
> 
> As the developer of a Swift database library, I'd like to offer a better API 
> than the following:
> 
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
> 
> Instead, I wish I could offer GRDB.swift would let its users write:
> 
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
> 
> And this requires genericity on return type.

Massive +1 to that

> 
> Gwendal
> 
> ___
> 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] Generic Subscripts

2017-01-14 Thread Gwendal Roué via swift-evolution
>>> Where generic subscripts are concerned, there are a couple of different 
>>> things to express:
>>> - Generic parameter  (I can understand various co-ordinates for the data)
>>> - Generic return type (I can construct your preferred representation of the 
>>> data)
>>> - Generic setter type (I can set the data using various compatible types):
>> 
>> I think all of these should be expressed with a single generic signature on 
>> the subscript itself. The element type passed to the setter and returned 
>> from the getter should be the same IMO, otherwise it’s not clear how it will 
>> work.
> 
> Yes.  It's quite important that any particular subscript reference is still a 
> single consistent entity, even if generic; we would not want, say, a 
> read-modify-write access to be able to somehow invoke the getter and setter 
> at different generic arguments, or to traffic in different element types.
> 
> I'm also not sure we'd ever want the element type to be inferred from context 
> like this.  Generic subscripts as I see it are about being generic over 
> *indexes*, not somehow about presenting a polymorphic value.

This is a consequence of your vision of subscript. If interesting, it is also 
limiting for no real purpose.

As the developer of a Swift database library, I'd like to offer a better API 
than the following:

// Current state of affairs
let name: String = row.value(named: "name")
let bookCount: Int = row.value(named: "bookCount")
let hasBooks: Bool = row.value(named: "bookCount")

Instead, I wish I could offer GRDB.swift would let its users write:

// With improved subscripts
let name: String = row["name"]
let bookCount: Int = row["bookCount"]
let hasBooks: Bool = row["bookCount"]

And this requires genericity on return type.

Gwendal

___
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-14 Thread Benjamin Spratling via swift-evolution
I notice the BinaryInteger's func word(at n: Int) -> UInt  function expects a 
2's complement representation.  Do you expect that "BigInt" will be implemented 
with 2's complement?  As a nonmutating function, I would think any 
implementation from a 1's complement big int would result in O(n^2) unless the 
BigInt were designed with scratch space where it could store the intermediate 
values of that representation.  I only ask because just last week I was 
designing an arbitrary-width float type in 1's complement, well, really I kept 
the sign bit in a separate Bool.  Of course, I recognize the value of being 
able to write integer init code from a 2's complement representation, I'm just 
curious if there's a way to allow this function to be more efficient for 
alternate representations.

I love that there's a DoubleWidth type, having coded some arbitrary precision 
arithmetic, that's always a downer going from generic code to having to pick a 
specific "big enough" result type.  

I'm glad the % operator got moved.  It really did stand out as not part of 
floating points.

Trailing zeros looks like a sensible optimization.

I agree with moving the shift operators, I like that you've called out the 
notion of an infinite shift.  I can't say I fully understood the use of the 
separate mask vs. smart shift operators, but I'll take another read in the next 
few days and see if I understand why they exist.

I know this PR does not address the BitInt implementation, but do you have one?

I'm glad to see this moving forward.

-Ben Spratling
Sent from my iPad

> On Jan 14, 2017, at 2:00 AM, Rien via swift-evolution 
>  wrote:
> 
> +1
> 
> Any change of including “ranged integers”?
> I.e. an integer with a value that must fit in a predefined range?
> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Swiftrien
> Project: http://swiftfire.nl
> 
> 
> 
> 
>> On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution 
>>  wrote:
>> 
>> Hi everyone,
>> 
>> Back in June 2016 we discussed the new design of the integer types for the 
>> standard library. It even resulted in acceptance of SE-0104 for Swift 3. 
>> Unfortunately we were not able to implement it in time for the release.
>> 
>> But it was not forgotten, although, as time went by, a few changes needed to 
>> be made in order to reflect the current state of the language.
>> Without further introduction, please welcome the refined proposal to make 
>> integers in Swift more suitable for generic programming.
>> 
>> Available in this gist 
>> https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c and also 
>> inlined below.
>> 
>> Max
>> 
>> Protocol-oriented integers (take 2)
>> 
>>• Proposal: SE-
>>• Authors: Dave Abrahams, Maxim Moiseev
>>• Review Manager: TBD
>>• Status: Awaiting review
>>• Bug: SR-3196
>>• Previous Proposal: SE-0104
>> Introduction
>> 
>> This proposal is an evolution of SE-0104. The goal is still to clean up 
>> Swifts integer APIs and make them more useful for generic programming.
>> 
>> The language has evolved in ways that affect integers APIs since the time 
>> the original proposal was approved for Swift 3. We also attempted to 
>> implement the proposed model in the standard library and found that some 
>> essential APIs were missing, whereas others could be safely removed.
>> 
>> Major changes to the APIs introduced by this proposal (as compared to 
>> SE-0104) are listed in a dedicated section.
>> 
>> Motivation
>> 
>> Swift's integer protocols don't currently provide a suitable basis for 
>> generic programming. See this blog post for an example of an attempt to 
>> implement a generic algorithm over integers.
>> 
>> The way the Arithmetic protocol is defined, it does not generalize to 
>> floating point numbers and also slows down compilation by requiring every 
>> concrete type to provide an implementation of arithmetic operators, thus 
>> polluting the overload set.
>> 
>> Converting from one integer type to another is performed using the concept 
>> of the 'maximum width integer' (see MaxInt), which is an artificial 
>> limitation. The very existence of MaxInt makes it unclear what to do should 
>> someone implement Int256, for example.
>> 
>> Another annoying problem is the inability to use integers of different types 
>> in comparison and bit-shift operations. For example, the following snippets 
>> won't compile:
>> 
>> var x: Int8 = 42
>> let y = 1
>> let z = 0
>> 
>> 
>> x 
>> <<= y   // error: binary operator '<<=' cannot be applied to operands of 
>> type 'Int8' and 'Int'
>> if x > z { ... }  // error: binary operator '>' cannot be applied to 
>> operands of type 'Int8' and 'Int'
>> Currently, bit-shifting a negative number of (or too many) bits causes a 
>> trap on some platforms, which makes low-level bit manipulations needlessly 
>> dangerous and unpredictable.

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

2017-01-14 Thread Rien via swift-evolution
+1

Any change of including “ranged integers”?
I.e. an integer with a value that must fit in a predefined range?

Regards,
Rien

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




> On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution 
>  wrote:
> 
> Hi everyone,
> 
> Back in June 2016 we discussed the new design of the integer types for the 
> standard library. It even resulted in acceptance of SE-0104 for Swift 3. 
> Unfortunately we were not able to implement it in time for the release.
> 
> But it was not forgotten, although, as time went by, a few changes needed to 
> be made in order to reflect the current state of the language.
> Without further introduction, please welcome the refined proposal to make 
> integers in Swift more suitable for generic programming.
> 
> Available in this gist 
> https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c and also 
> inlined below.
> 
> Max
> 
> Protocol-oriented integers (take 2)
> 
>   • Proposal: SE-
>   • Authors: Dave Abrahams, Maxim Moiseev
>   • Review Manager: TBD
>   • Status: Awaiting review
>   • Bug: SR-3196
>   • Previous Proposal: SE-0104
> Introduction
> 
> This proposal is an evolution of SE-0104. The goal is still to clean up 
> Swifts integer APIs and make them more useful for generic programming.
> 
> The language has evolved in ways that affect integers APIs since the time the 
> original proposal was approved for Swift 3. We also attempted to implement 
> the proposed model in the standard library and found that some essential APIs 
> were missing, whereas others could be safely removed.
> 
> Major changes to the APIs introduced by this proposal (as compared to 
> SE-0104) are listed in a dedicated section.
> 
> Motivation
> 
> Swift's integer protocols don't currently provide a suitable basis for 
> generic programming. See this blog post for an example of an attempt to 
> implement a generic algorithm over integers.
> 
> The way the Arithmetic protocol is defined, it does not generalize to 
> floating point numbers and also slows down compilation by requiring every 
> concrete type to provide an implementation of arithmetic operators, thus 
> polluting the overload set.
> 
> Converting from one integer type to another is performed using the concept of 
> the 'maximum width integer' (see MaxInt), which is an artificial limitation. 
> The very existence of MaxInt makes it unclear what to do should someone 
> implement Int256, for example.
> 
> Another annoying problem is the inability to use integers of different types 
> in comparison and bit-shift operations. For example, the following snippets 
> won't compile:
> 
> var x: Int8 = 42
> let y = 1
> let z = 0
> 
> 
> x 
> <<= y   // error: binary operator '<<=' cannot be applied to operands of type 
> 'Int8' and 'Int'
> if x > z { ... }  // error: binary operator '>' cannot be applied to operands 
> of type 'Int8' and 'Int'
> Currently, bit-shifting a negative number of (or too many) bits causes a trap 
> on some platforms, which makes low-level bit manipulations needlessly 
> dangerous and unpredictable.
> 
> Finally, the current design predates many of the improvements that came since 
> Swift 1, and hasn't been revised since then.
> 
> Proposed solution
> 
> We propose a new model that does not have above mentioned problems and is 
> more easily extensible.
> 
> +--+  +-+
> +-->+  Arithmetic  |  | Comparable  |
> |   |   (+,-,*,/)  |  | (==,<,>,...)|
> |   +-++  +---+-+
> | ^   ^
> +---++|   |
> |  SignedArithmetic  |  +-+---+---+
> | (unary -)  |  |BinaryInteger|
> +--+-+  |(words,%,bitwise,...)|
>^++---+-+--+
>| +---^   ^ ^---+
>| |   | |
> +--+-+++-+---+  +--++
> |  SignedInteger  ||  FixedWidthInteger  |  |  UnsignedInteger  |
> | ||(endianness,overflow,...)|  |   |
> +---+-++-++--+  +-+-+
> ^^^   ^
> |||   |
> |||   |
>+++-++-+---+-+
>|Int family |-+  |UInt family|-+
>+---+ |  +---+ |
>  +---++---+
> 
> There are several benefits provided by this model over the old one:
> 
>   • It allows mixing integer types in generic functions.
> 
> The