Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 16, 2018 at 6:31 PM, Xiaodi Wu  wrote:

> On Tue, Jan 16, 2018 at 4:30 PM, Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
>> The thing that is “broken” here is generic programming. If I constrain
>> something to FloatingPoint, I cannot use a float literal in calculations
>> with it:
>>
>> func centimeters (inches: T) -> T {
>>
>> return 2.54 * inches// Error
>>
>> }
>>
>
> Why not constrain it to `BinaryFloatingPoint`? What other types are you
> trying to use with this function?
>

We should not ask nor expect people to constrain their generic algorithms
to BinaryFloatingPoint unless they are working with the radix.



> so that eg. a Rational type could be used. And that gives a hint as to the
>> workaround:
>>
>> func centimeters (inches: T) -> T {
>>
>> return (254 / 100) * inches
>>
>> }
>>
>
> Yes, you *could* do that.
>

And it seems I *will* be doing that, as long as such a workaround is
necessary. Though it does appear to have the unfortunate cost of an extra
division operation.


That only works for numbers which don’t overflow the integer literals
>> though.
>>
>
> Integer literals don't overflow until 2048 bits. The following compiles
> just fine:
>
> func moles(particles: T) -> T {
>   let N_A: T = 602_214_085_774_000_000_000_000
>   return particles / N_A
> }
>

When I write that in a playground it shows N_A as 1.67866967797794e+18.

(Also, you appear to have mistakenly concatenated the standard uncertainty
in the last 2 digits, “74”, onto the accepted value for the constant.)


If we want a really large or small value then we have to split it in pieces:
>>
>> func moles  (particles: T) -> T {
>>
>> let avogadroNumber: T = 6_022_140_857 * 100_000_000_000_000
>>
>> return particles / avogadroNumber
>>
>> }
>>
>> It would be much nicer to write “let avogadroNumber: T = 6.022140857e23”.
>>
>
> You could write:
>
> func moles(particles: T)
> -> T {
>   let N_A = T("6.02214085774e+23")!
>   return particles / N_A
> }
>

…or I could write “T: FloatingPoint & ExpressibleByFloatLiteral”. I could
even make a typealias for that. But I shouldn’t have to.

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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-16 Thread Nevin Brackett-Rozinsky via swift-evolution
The thing that is “broken” here is generic programming. If I constrain
something to FloatingPoint, I cannot use a float literal in calculations
with it:

func centimeters (inches: T) -> T {

return 2.54 * inches// Error

}

Of course, “T: FloatingPoint” is an overconstraint in this example, as what
I actually want is “T: OrderedField” so that eg. a Rational type could be
used. And that gives a hint as to the workaround:

func centimeters (inches: T) -> T {

return (254 / 100) * inches

}

That only works for numbers which don’t overflow the integer literals
though. If we want a really large or small value then we have to split it
in pieces:

func moles  (particles: T) -> T {

let avogadroNumber: T = 6_022_140_857 * 100_000_000_000_000

return particles / avogadroNumber

}

It would be much nicer to write “let avogadroNumber: T = 6.022140857e23”.

Nevin


On Tue, Jan 16, 2018 at 3:39 PM, Chris Lattner  wrote:

> On Jan 15, 2018, at 11:01 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
> > - Can we change the semantics? Maybe, but I doubt
> ExpressibleByFloatLiteral can be outright replaced. You're not the first to
> wonder about how to design an alternative protocol. Dig through the
> archives and you'll find some existing ideas. My two cents: The main
> alternative base in question here is 10. However, decimal storage formats
> and binary storage formats share so little in common that any initializer
> common to both will be extremely unwieldy for one or both formats.
> Personally, somewhere down the road, I'd rather see Decimal64/128 become
> standard library types (already working on it), DecimalFloatingPoint become
> a standard library protocol, and `0.1` become a "decimal literal" (with
> Float, Double, Float80, and Decimal64/128 all conforming) as distinct from
> a "float literal" that we could then restrict to hexadecimal (?and binary)
> floating-point literals (and maybe rename accordingly).
>
> If we were motivated to fix this (and I’m not :-), then I think the best
> path forward would be to rename ExpressibleByFloatLiteral to something like
> ExpressibleByBinaryFloatLiteral.  This would allow the introduction of a
> new ExpressibleByDecimalFloatLiteral with a different initializer
> requirement.
>
> I’m not motivated to fix this, because there is nothing actively broken by
> the current state of things.  With the current name we can still introduce
> a ExpressibleByDecimalFloatLiteral someday in the future.  The two names
> will be a little odd, but given the cost of changing it at this point, that
> seems perfectly acceptable.
>
> -Chris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
I should have been more clear: APIs that we add through Swift Evolution
would continue to be permanent additions to the language just as they are
today. I was not suggesting otherwise. However, the underlying
behind-the-scenes ABI-related aspects of their implementations would
initially be malleable, so the optimization wizards on Swift Dev could have
a chance to do their thing.

For example, the String ABI thread on Swift Dev has discussion about
various aspects of the String type’s implementation, which do not affect
API but do need to be settled before ABI stability. Similar decisions may
need to be made about other types, and this idea of Xiaodi’s and Chris’s
would keep that option open.

Nevin



On Tue, Jan 16, 2018 at 1:39 AM, Ted Kremenek  wrote:

> Hi Nevin,
>
> I think this is an interesting perspective.  For me it begets the question
> of how an API “gets finalized”.  Currently anything that goes through the
> Swift Evolution proposal process that gets ratified is considered an
> official change to the language and Standard Library.  That feels like
> “finalized” to me, unless we want to introduce some new affordances to the
> process that allow us to introduce new APIs that are clearly going through
> a trial.  I think that’s a very interested idea (which is one Xiaodi
> proposed), but that’s not something we have today.
>
> On this thread we are talking about APIs that have been in the Standard
> Library for a while, and largely predate the Swift Evolution process.  What
> makes them less finalized versus other APIs with similar heritage?  These
> APIs are in use, albeit Chris points out that they are (most likely)
> uncommonly used.  A core deliverable of ABI stability, however, is that the
> majority of the Standard Library is in a binary stable form.  The only APIs
> I think we can consider candidates for a “deprecated” dylib that gets
> embedded in the app are “leaf” APIs that are uncommonly used by clients and
> not relied upon by other parts of the Standard Library that are commonly
> used by clients.  Practically speaking, however, I’m not convinced that set
> is so large to add the complexity/engineering cost/time of creating this
> separate dylib right now.  Those APIs can’t get ripped out right now —
> after all they’ve been in there for a while and we’re not deprecating them
> because there aren’t alternatives that exist yet anyway.  Thus these APIs
> need to continue to exist, and the benefits to me to create this separate
> dylib for those old “warty” APIs that we may — one day — want to replace
> seems marginal.
>
> I do think the idea of having a way to add *new* ABI-unstable APIs is very
> interesting, but I think the root of this discussion comes from talking
> about APIs that have been around for a while but feel like potential warts
> as we approach ABI stability.  I hate to say it, but there will be warts
> regardless.  There’s a lot to do for ABI stability — it’s making good
> progress — but not every last change we may have wanted to do will get all
> the attention we may have originally hoped it would.  Getting ABI stability
> done for Swift 5 is about prioritization and best effort, which includes
> accepting that not everything is going to be perfect.
>
> Ted
>
> On Jan 15, 2018, at 1:04 PM, Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
> Alternatively, from a different perspective, rather than adding a new
> ABI-unstable library that gets bundled with apps, another way to look at it
> is that we already *have* an ABI-unstable library that gets bundled with
> apps. So we can instead think about introducing a new library with a stable
> ABI, which can be distributed with the OS.
>
> That way, as each piece of the existing standard library gets finalized,
> we can move it into the new ABI-stable library. Some pieces (eg. Mirror)
> will never make the jump and can be phased out eventually. And when future
> proposals make additions to the standard library, they can begin life in
> the original, existing, non-ABI-stable library.
>
> The net effect is the same as what we have been discussing, but a shift in
> viewpoint makes it clear that the ABI-stable library is the new thing we
> are adding, and the existing standard library can continue to serve a
> valuable purpose going forward.
>
> Nevin
>
>
>
> On Sun, Jan 14, 2018 at 9:04 PM, Ted Kremenek via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>>
>> > On Jan 12, 2018, at 11:23 PM, Chris Lattner 
>> wrote:
>> >
>> > On Jan 12, 2018, at 4:43 PM, Ted Kremenek  wrote:
>> >> Hi Chris,
>> >>
>> >> Instead of responding to each of your point bit-by-bit, I’ll try a
>> different tactic to explain my reasoning — which may be wrong — by
>> explaining how I see things top down with the tradeoffs they incur.  I’m
>> going to say a bunch of things I know *you* know, but others are on this
>> thread and I’ll state things for end-to-end clarity.
>> >
>> > Sounds good.
>> >
>> >> It seems to me that 

Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Jan 15, 2018 at 11:27 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 20:37 Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
>>
>> That protocol is spelled ExpressibleByFloatLiteral, which reflects the
>> meaning that we want and should have. The name is correct, the problem is
>> with the implementation.
>>
>
> I get that you want float literals to have semantics other than what they
> have. Again, that's a different conversation.
>

It is the exact conversation I started this thread to have, so if there is
any other conversation going on here then *that* is the different one. :-)

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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Jan 15, 2018 at 8:51 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 19:20 Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
>
>> All I’m saying is the current situation seems semantically wrong. As in,
>> how can a type claim to be a floating point number, if it *literally*
>> cannot be represented by a floating point number?
>>
>
> Again, you can think of it that way, but what I’m saying is that
> “FloatLiteral” is a misnomer: semantically, a conforming type is
> specifically claiming that it is expressible by a _binary_ floating point
> number.
>

 I strongly disagree. To say that it is a “misnomer” implies that the
semantics are correct and the problem is with the name.

However, in Swift a floating point literal consists of certain patterns of
characters in source code, as specified by the language grammar. Thus it is
meaningful and correct to say that certain types can be expressed as
floating point literals. We have a protocol for exactly that purpose: to
indicate that conforming types can be written as floating point literals.

That protocol is spelled ExpressibleByFloatLiteral, which reflects the
meaning that we want and should have. The name is correct, the problem is
with the implementation.

If you want to argue that, after we fix the buggy implementation of
ExpressibleByFloatLiteral, then we should introduce a new protocol named
ExpressibleByBinaryFloatLiteral, that might be a discussion worth having.
But for the existing protocol, renaming it would not solve the underlying
issue.

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


Re: [swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
All I’m saying is the current situation seems semantically wrong. As in,
how can a type claim to be a floating point number, if it *literally*
cannot be represented by a floating point number?

You suggest treating a float literal as a string, but another alternative
is to teach the compiler to handle arbitrary-length integer literals, and
then treat a float literal as two integer literals separated by a dot.

In any case, is this something that would have to be done before ABI
stability, or could it wait until after?

Nevin


On Mon, Jan 15, 2018 at 7:41 PM, Xiaodi Wu  wrote:

> On Mon, Jan 15, 2018 at 4:24 PM, Nevin Brackett-Rozinsky via
> swift-evolution  wrote:
>
>> Currently, the FloatingPoint protocol does not conform to
>> ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.
>>
>> The only explanation I can find for this is a brief comment from Steve
>> Canon
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/015691.html>
>> during the review of SE-0067 (Enhanced Floating Point Protocols)
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0067-floating-point-protocols.md>
>> :
>>
>>
>> On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
>>>  wrote:
>>>
>>> On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
>>>>  wrote:
>>>>
>>>> Any reason why FloatLiteralConvertible isn't on FloatingPoint?
>>>
>>>
>>> It doesn’t make sense for non-radix-2 types; you would change bases
>>> multiple times.
>>
>>
>>
>> I don’t have Steve’s level of floating-point expertise, but from a
>> conceptual standpoint Swift protocols encapsulate semantics and, unless I
>> am quite mistaken, semantically a floating-point number *can* be expressed
>> as a floating-point literal.
>>
>> So, what exactly is the problem preventing such a conformance, and what
>> would be required to fix it? Do we need to revamp how numeric literals are
>> handled, eg. to allow arbitrary-precision integers and base-agnostic floats?
>>
>
> Note that there are no types that ship with Swift itself that conform to
> FloatingPoint but not BinaryFloatingPoint (Foundation.Decimal does not
> conform to FloatingPoint, and cannot do so without some major
> backwards-incompatible surgery because of how it handles subnormals,
> infinity, NaN, and a host of other issues), so this discussion does not
> affect most (any?) end users.
>
>
> The name ExpressibleByFloatLiteral is kind of a misnomer. To conform, a
> type must be able to convert a value from some other type that conforms to _
> ExpressibleByBuiltinFloatLiteral, which is to say a _binary_
> floating-point type.
>
> If you create a Decimal type, it *could try to conform* to
> ExpressibleByFloatLiteral, but given `var x: Double = 0.1`, the value would
> actually be something like 0.10001, not exactly 0.1, because
> it'd be the decimal approximation of a _binary_ approximation to the
> literal. This is what Steve means by "you would change bases multiple
> times," and the result is unintuitive. The alternative is to try to convert
> to a decimal value via the _string representation_ of the _binary
> approximation_ to the literal, which would let you recover `0.1` but lose
> all information as to significant digits in the original literal (i.e.,
> "0.1" vs. "0.100"), an important piece of information for Decimal types.
>
> In other words, given the actual design of ExpressibleByFloatLiteral, it
> doesn't entirely make sense for non-binary floating-point types to conform.
>
>
> Yes, we can try to perform major surgery on the floating-point literal
> protocol, or add another one, so that it's possible for non-binary types to
> conform, and there have been proposals on this list along those lines. It
> would appear to me that any such design would necessarily be more complex
> and possibly slower than the existing design; at its simplest, it could
> involve representing the literal as a string, which almost all types,
> whether Decimal or BigInt, would expected to be able to parse anyway. But
> that's a much larger discussion for another day. The answer to your
> question as to why `FloatingPoint` does not refine
> `ExpressibleByFloatLiteral` is as shown above; tl;dr: it doesn't make sense
> to do so.
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] FloatingPoint does not conform to ExpressibleByFloatLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
Currently, the FloatingPoint protocol does not conform to
ExpressibleByFloatLiteral, whereas BinaryFloatingPoint does.

The only explanation I can find for this is a brief comment from Steve Canon

during the review of SE-0067 (Enhanced Floating Point Protocols)

:


On Mon, Apr 25, 2016 at 1:32 PM, Stephen Canon via swift-evolution
>  wrote:
>
> On Apr 23, 2016, at 8:53 PM, Brent Royal-Gordon via swift-evolution
>>  wrote:
>>
>> Any reason why FloatLiteralConvertible isn't on FloatingPoint?
>
>
> It doesn’t make sense for non-radix-2 types; you would change bases
> multiple times.



I don’t have Steve’s level of floating-point expertise, but from a
conceptual standpoint Swift protocols encapsulate semantics and, unless I
am quite mistaken, semantically a floating-point number *can* be expressed
as a floating-point literal.

So, what exactly is the problem preventing such a conformance, and what
would be required to fix it? Do we need to revamp how numeric literals are
handled, eg. to allow arbitrary-precision integers and base-agnostic floats?

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


Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-15 Thread Nevin Brackett-Rozinsky via swift-evolution
Alternatively, from a different perspective, rather than adding a new
ABI-unstable library that gets bundled with apps, another way to look at it
is that we already *have* an ABI-unstable library that gets bundled with
apps. So we can instead think about introducing a new library with a stable
ABI, which can be distributed with the OS.

That way, as each piece of the existing standard library gets finalized, we
can move it into the new ABI-stable library. Some pieces (eg. Mirror) will
never make the jump and can be phased out eventually. And when future
proposals make additions to the standard library, they can begin life in
the original, existing, non-ABI-stable library.

The net effect is the same as what we have been discussing, but a shift in
viewpoint makes it clear that the ABI-stable library is the new thing we
are adding, and the existing standard library can continue to serve a
valuable purpose going forward.

Nevin



On Sun, Jan 14, 2018 at 9:04 PM, Ted Kremenek via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> > On Jan 12, 2018, at 11:23 PM, Chris Lattner  wrote:
> >
> > On Jan 12, 2018, at 4:43 PM, Ted Kremenek  wrote:
> >> Hi Chris,
> >>
> >> Instead of responding to each of your point bit-by-bit, I’ll try a
> different tactic to explain my reasoning — which may be wrong — by
> explaining how I see things top down with the tradeoffs they incur.  I’m
> going to say a bunch of things I know *you* know, but others are on this
> thread and I’ll state things for end-to-end clarity.
> >
> > Sounds good.
> >
> >> It seems to me that we are talking about two possible scenarios: (1)
> the status quo of keeping everything in libswiftCore.dylib or (2) splitting
> libswiftCore.dylib into two dylibs, one which includes some of the
> “deprecated” APIs.  I’ll enumerate what I think are the tradeoffs/benefits
> we will see with both scenarios, and see where the mismatch in our “talking
> past each other” is happening.
> >
> > Right.
> >
> >> In both cases (A) and (B), with ABI stability the Standard Library has
> the option to ship in the OS.  Thus applications using Swift on (say) iOS
> would no longer need to include libswiftCore.dylib in the app when running
> on an OS that shipped with the Standard Library.
> >
> > Right.  Please keep in mind that both approaches also eliminate all the
> overlay dylibs for those apps, and both approaches put the vast majority of
> the stdlib code into the OS as well.  The ‘deprecated’ dylib is probably
> going to be comparatively small.
> >
> >> With that in mind, here are the tradeoffs as I see between scenarios
> (A) and (B):
> >>
> >> (A) Status quo: Keep shipping everything in libswiftCore.dylib
> >>
> >> - Applications running on an OS with the Standard Library would no
> longer have *any* of the currently libswift*.dylib’s embedded inside the
> application bundle because they would just use the one in the OS.
> >
> > Right.
> >
> >> - One benefit of using libswift*.dylibs in the OS as opposed to those
> embedded inside the app bundle is that there is a non-neglible startup time
> improvement, as the code signing verification that happens when an app
> launches would be faster as it would not need to verify each of these
> dylibs that were previously embedded in the app.  We should consider this
> the new baseline for app startup time for an app running on an OS with an
> ABI stable Standard Library.
> >
> > This happens with both models.  Refer back to the dyld optimization WWDC
> talk by Nick and Louis 2-3 years ago.  The big problem with Swift for
> startup time is that it adds half a dozen (or more) dylibs to your app
> bundle.  In the talk they make it clear that adding a single dylib is not a
> big deal, it is adding a bunch of dylibs that is the problem, particularly
> if they have interdependencies between them.
>
> Right — it is the large volume of dylibs that is the problem.
>
> >
> > Neither approach presents this performance problem.
>
> Agreed — in practice neither scenario is much different.
>
> >
> > Further, if it were important to solve this startup time problem, it is
> straight-forward to solve it for apps that do want to deploy backward
> (which will be almost all of them in NMOS).  You’d do this by merging all
> the dylibs into a single one in the app bundle instead of leaving them to
> be independently resolved at load time.
> >
> >> - We continue to support the deprecated APIs for some time, possibly
> indefinitely, even when better alternatives come around.
> >
> > Agreed.
> >
> >> (B) Split libswiftCore.dylib into two dylibs, one that gets embedded in
> the app bundle
> >>
> >> In the second scenario, we split out the deprecated APIs into a
> separate dylib, say libswiftCoreDeprecated.dylib.  That solution would have
> the following characteristics:
> >>
> >> - Like scenario (A), app bundles would not need to embed
> libswiftCore.dylib when running on an OS that had an ABI-stable Standard
> Library.
> >>
> >> - Compared to scena

Re: [swift-evolution] [Pitch] Make try? + optional chain flattening work together

2018-01-12 Thread Nevin Brackett-Rozinsky via swift-evolution
This is not an optional-chaining issue *per se*. If you simply write,

let a = try? SomeType().doThrow()

// a has type SomeType??

you get a double-optional as well. Are you proposing to change that?

Nevin


On Fri, Jan 12, 2018 at 12:25 PM, Russ Bishop via swift-evolution <
swift-evolution@swift.org> wrote:

> Greetings swift-evolution!
>
> There is currently a disconnect between optional chaining and try? when it
> comes to optional flattening:
>
>
> struct SomeType {
> func nonThrow() -> SomeType? { return self }
> func doThrow() throws -> SomeType? { return self }
> func nonOptional() throws -> SomeType { return self }
> }
>
> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
> // w has type SomeType?
>
> let x = try? SomeType().nonOptional().nonOptional().nonOptional().nonOpti
> onal()
> // x has type SomeType?
>
> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // y has type SomeType?
>
> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
> // z has type SomeType??
>
>
> We get a double-optional only when combining try? and optional-chaining.
> That is inconvenient and it would be natural to have the compiler do the
> flattening here.
>
>
> If anyone is interested in working on the proposal or implementation
> please let me know. It would make a nice self-contained task if you're
> looking to start contributing.
>
>
> Russ Bishop
>  Simulator
>
>
>
> ___
> 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] Random Unification

2018-01-10 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Jan 10, 2018 at 6:02 PM, Jens Persson via swift-evolution <
swift-evolution@swift.org> wrote:

> I agree.
>
> If there should be an API to produce a random Double without parameters
> then IMHO it should simply be a uniformly distributed Double in the unit
> range [0, 1). Very useful as a basic building block and can be constructed
> very fast from a random bitpattern like eg:
> extension Double {
> init(unitRange v: UInt64) {
> self = Double(v >> Double.exponentBitCount) * (.ulpOfOne/2.0)
> }
> }
>

The implementation of randomness for floating point types deserves in-depth
consideration. I know that we have some IEEE-754 experts on this list, and
it would be great to have them weigh in. For instance…

When generating a uniformly-distributed floating point number in a
half-open range with finite bounds, should every representable value in
that range be possible to produce? If so, should each representable value v
appear with probability proportional to (v.nextUp - v), which may be
different from (x.ulp)?

In other words, conceptually, should the API behave as if a real number
were chosen uniformly from the range, then rounded down to the closest
representable value that does not exceed it?

Or should some fixed number of equally-spaced values that span the range be
the only possible results?

Or something else?

Should subnormal values be producible?

There is no uniform distribution over an infinite-length continuum, so how
should infinite ranges be handled? In the range (0.0 ..< .infinity) should
we always return .greatestFiniteMagnitude? And in (-.infinity ..< 0.0)
should we always return (-.infinity)? What about (-.infinity ..<
.infinity)? Should there be preconditions that can fail at runtime, or
should we sometime return .nan, or what?

• • •

These are just a few of the questions that spring to mind, so I think it is
highly important that floating-point randomness gets sufficient attention
to ensure that we land on a well-considered design.

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


Re: [swift-evolution] Incremental ABI stability

2018-01-10 Thread Nevin Brackett-Rozinsky via swift-evolution
For reference, Chris’s idea can be found here
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20180108/042668.html>
.

Nevin


On Wed, Jan 10, 2018 at 5:22 PM, Hooman Mehr via swift-evolution <
swift-evolution@swift.org> wrote:

> I think the best solution is Chris Lattner’s suggestion (responding to
> DictionaryLiteral) to split the shaky stuff into an overlay for Swift
> standard library to maintain compatibility.
>
> On Jan 10, 2018, at 2:12 PM, Greg Parker via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jan 9, 2018, at 6:50 PM, Jon Hull via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Jan 9, 2018, at 6:30 PM, Nevin Brackett-Rozinsky via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I’m just spitballing here, and I’m not an expert on matters of ABI,
> however the thought occurs to me that the current all-or-nothing approach
> might lead to suboptimal results.
>
> In particular, some recent discussions on this list have mentioned that
> certain parts of the standard library, such as Mirror, really ought to be
> redesigned. But their current shape is on track to be baked into the
> permanent ABI, even though we know right now that we can do better.
>
> Has any consideration been given to the possibility of carving out
> specific exemptions to ABI stability for Swift 5, and saying something
> like, “The entire ABI will be stabilized, except for Mirror (and possibly a
> small number of other things)”?
>
> That way we can nail down almost all of the ABI, while still being able to
> fix the parts that we can already see need fixing. Perhaps I am being naive
> here, and I’m sure there are major aspects I am unaware of, but from my
> layperson’s perspective it seems rather silly to tie ourselves to a legacy
> implementation that we want to redesign.
>
>
> I would like to be even more conservative, only locking down the things we
> know we have received actual human attention of some sort. The
> all-or-nothing approach is actively harmful in my mind.
>
>
> This model is unlikely to work well.
>
> Any feature that lacks stable ABI is equivalent to saying "if you use this
> feature in your app then your app will crash or worse on some future OS
> version". That in turn leads to two likely outcomes:
> 1. Apps use the feature. In some future OS version we break them and they
> crash. Users are unhappy.
> 2. Apps use the feature. In some future OS version we decide that we can't
> afford to break them. The "unstable" ABI becomes locked down anyway.
>
> I think we're more likely to simply delete a feature with no replacement
> than to do the above.
>
>
> --
> Greg Parker gpar...@apple.com Runtime Wrangler
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>

On Wed, Jan 10, 2018 at 5:22 PM, Hooman Mehr via swift-evolution <
swift-evolution@swift.org> wrote:

> I think the best solution is Chris Lattner’s suggestion (responding to
> DictionaryLiteral) to split the shaky stuff into an overlay for Swift
> standard library to maintain compatibility.
>
> On Jan 10, 2018, at 2:12 PM, Greg Parker via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jan 9, 2018, at 6:50 PM, Jon Hull via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Jan 9, 2018, at 6:30 PM, Nevin Brackett-Rozinsky via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I’m just spitballing here, and I’m not an expert on matters of ABI,
> however the thought occurs to me that the current all-or-nothing approach
> might lead to suboptimal results.
>
> In particular, some recent discussions on this list have mentioned that
> certain parts of the standard library, such as Mirror, really ought to be
> redesigned. But their current shape is on track to be baked into the
> permanent ABI, even though we know right now that we can do better.
>
> Has any consideration been given to the possibility of carving out
> specific exemptions to ABI stability for Swift 5, and saying something
> like, “The entire ABI will be stabilized, except for Mirror (and possibly a
> small number of other things)”?
>
> That way we can nail down almost all of the ABI, while still being able to
> fix the parts that we can already see need fixing. Perhaps I am being naive
> here, and I’m sure there are major aspects

Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-09 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 9, 2018 at 9:27 PM, Hooman Mehr via swift-evolution <
swift-evolution@swift.org> wrote:

> I think this type might become more useful if we find a good name for it
> and better document it. For example, it is a natural fit for parameter list
> of Chris’ callable type proposal.
>
> Since this type accepts duplicate “keys” and does not provide key-based
> lookup, the first thing that deserves a rename is “Key” generic parameter.
> I recommend naming it “Label”.
>
> This type represents how a dictionary literal *looks*, not what it *means*.
> When we consider the look of it, a dictionary literal is an array literal
> where each element is labeled.
>
> I can’t think of a really good name, but we may be able to find a more
> accurate and less confusing name.
>
> Some of the more accurate names are:
>
> LabeledElementCollection
> LabeledValueCollection
> LabeledValueList
> LabeledList
>
> By the way, why this type does not conform to any of the collection
> protocols while duplicating a lot of collection APIs?
>


+1 to “LabeledList”

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


[swift-evolution] Incremental ABI stability

2018-01-09 Thread Nevin Brackett-Rozinsky via swift-evolution
I’m just spitballing here, and I’m not an expert on matters of ABI, however
the thought occurs to me that the current all-or-nothing approach might
lead to suboptimal results.

In particular, some recent discussions on this list have mentioned that
certain parts of the standard library, such as Mirror, really ought to be
redesigned. But their current shape is on track to be baked into the
permanent ABI, even though we know right now that we can do better.

Has any consideration been given to the possibility of carving out specific
exemptions to ABI stability for Swift 5, and saying something like, “The
entire ABI will be stabilized, except for Mirror (and possibly a small
number of other things)”?

That way we can nail down almost all of the ABI, while still being able to
fix the parts that we can already see need fixing. Perhaps I am being naive
here, and I’m sure there are major aspects I am unaware of, but from my
layperson’s perspective it seems rather silly to tie ourselves to a legacy
implementation that we want to redesign.

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


Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-09 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 9, 2018 at 7:47 PM, char...@charlesism.com <
charlesism@gmail.com> wrote:

> I used a DictionaryLiteral only yesterday, and it turned what would have a
> typically unreadable array of Structs into something much more elegant. I'm
> pretty sure the only reason Literals (of all varieties) aren't used more
> often is because Swift programmers don't realize they are available and
> easy to implement.
>

Could you provide an example of how you used DictionaryLiteral?

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


Re: [swift-evolution] 100% bikeshed topic: DictionaryLiteral

2018-01-08 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Jan 8, 2018 at 11:53 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> Thank you for the clarification. It occurred to me in the shower that this
> might be the case, and that I was entirely mistaken as to what we were
> talking about.
>
> Yes, then, I wholeheartedly agree on this point. Out of curiosity, why are
> there source stability issues to 'typealias DictionaryLiteral =
> [(Key, Value)]'?


Because at the point of use, “DictionaryLiteral” is instantiated with an
actual dictionary literal, eg. “[a: 1, b: 2, c: 3]”, and that syntax isn’t
available for an array of key-value pairs. As near as I can tell, the
convenience of that spelling is the entire *raison-d’être* for
“DictionaryLiteral” in the first place.

The ulterior question of whether preserving “DictionaryLiteral” is
worthwhile, is apparently out of scope. Personally, I have a hard time
imagining a compelling use-case outside of the standard library, and I
doubt it’s being used “in the wild” (I checked several projects in the
source-compatibility suite and found zero occurrences).

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


Re: [swift-evolution] DynamicMemberLookup proposal: status update

2018-01-04 Thread Nevin Brackett-Rozinsky via swift-evolution
There’s a lot of information here and it’ll take some time to process it
all. My initial reaction is that a “strong type-alias” feature might help.
If one could write (strawman syntax):

strong typealias Dog = PyVal// A semantically independent new type

extension Dog {
// Declarations here are only available on “Dog”, not on “PyVal”
}

then most of the overload issues would evaporate.

Nevin



On Thu, Jan 4, 2018 at 3:52 PM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi everyone,
>
> With the holidays and many other things behind us, the core team had a
> chance to talk about python interop + the dynamic member lookup proposal
> recently.
>
> Here’s where things stand: we specifically discussed whether a
> counter-proposal of using “automatically generated wrappers” or “foreign
> classes” to solve the problem would be better.  After discussion, the
> conclusion is no: the best approach appears to be 
> DynamicMemberLookup/DynamicCallable
> or something similar in spirit to them.  As such, I’ll be dusting off the
> proposal and we’ll eventually run it.
>
> For transparency, I’m attaching the analysis below of what a wrapper
> facility could look like, and why it doesn’t work very well for Python
> interop.  I appologize in advance that this is sort of train-of-thought and
> not a well written doc.
>
> That said, it would be really great to get tighter integration between
> Swift and SwiftPM for other purposes!  I don’t have time to push this
> forward in the short term though, but if someone was interested in pushing
> it forward, many people would love to see it discussed seriously.
>
> -Chris
>
>
> *A Swift automatic wrapper facility:*
>
> Requirements:
>  - We want the be able to run a user defined script to generate wrappers.
>  - This script can have arbitrary dependencies and should get updated when
> one of them change.
>  - These dependencies won’t be visible to the Xcode build system, so the
> compiler will have to manage them.
>  - In principle, one set of wrappers should be able to depend on another
> set, and wants “overlays”, so we need a pretty general model.
>
> I don’t think the clang modules based approach is a good way to go.
>
>
> *Proposed Approach: Tighter integration between SwiftPM and Swift*
>
> The model is that you should be able to say (strawman syntax):
>
>import Foo from http://github.com/whatever/mypackage
>import Bar from file:///some/path/on/my/machine
>
> and have the compiler ask SwiftPM to build and cache the specified module
> onto your local disk, then have the compiler load it like any other
> module.  This means that “generated wrappers” is now a SwiftPM/llbuild
> feature, and we can use the SwiftPM “language” to describe things like:
>
> 1. Information about what command line invocation is required to generate
> the wrappers.
> 2. Dependency information so that the compiler can regenerate the wrappers
> when they are out of date.
> 3. Platform abstraction tools since things are in different locations on
> linux vs mac, Python 2 vs Python 3 is also something that would have to be
> handled somehow.
> 4. The directory could contain manually written .swift code, serving the
> function similar to “overlays” to augment the automatic wrappers generated.
>
> We care about Playgrounds and the REPL, and they should be able to work
> with this model.
>
> I think that this would be a very nice and useful feature.
>
>
> *Using Wrappers to implement Python Interop:*
>
> While such a thing would be generally useful, it is important to explore
> how well this will work to solve the actual problem at hand, since this is
> being pitched as an alternative to DynamicMemberLookup.  Here is the
> example from the list:
>
> class BankAccount:
> def __init__(self, initial_balance: int = 0) -> None:
> self.balance = initial_balance
> def deposit(self, amount: int) -> None:
> self.balance += amount
> def withdraw(self, amount: int) -> None:
> self.balance -= amount
> def overdrawn(self) -> bool:
> return self.balance < 0
>
> my_account = BankAccount(15)
> my_account.withdraw(5)print(my_account.balance)
>
>
> The idea is to generate a wrapper like this (potentially including the
> type annotations as a refinement):
>
> typealias BankAccount = PyVal
> extension PyVal { // methods on BankAccount
>   init(initial_balance: PyVal) { … }
>   func deposit(amount: PyVal) -> PyVal { … }
>   func withdraw(amount: PyVal) -> PyVal { … }
>   func overdrawn() -> PyVal { … }
> }
>
> my_account = BankAccount(initial_balance: 15)
> my_account.withdraw(amount: 5)
> print(my_account.balance)
>
>
>
> It is worth pointing out that this approach is very analogous to the “type
> providers” feature that Joe pushed hard for months ago, it is just a
> different implementation approach.  The proposal specifically explains why
> this isn’t a great solution here:
> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae54

Re: [swift-evolution] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-04 Thread Nevin Brackett-Rozinsky via swift-evolution
On Thu, Jan 4, 2018 at 8:23 AM, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:

> On Jan 3, 2018, at 10:02 AM, Dave DeLong via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> 1️⃣ a @frozen/@tangled/@moana attribute for enums that’s only consulted on
> externally-linked modules
>
>
> Naming is serious business, Dave. Let it go.
>


Since the attribute means, “Don’t worry about new cases, this enum won’t
change for the rest of its days,” the optimal spelling is clearly
@hakunaMatata

We do still need a way for multi-module apps to work problem-free though.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-02 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

> [Proposal: https://github.com/apple/swift-evolution/blob/
> master/proposals/0192-non-exhaustive-enums.md]
>
> Whew! Thanks for your feedback, everyone. On the lighter side of
> feedback—naming things—it seems that most people seem to like '*@frozen*',
> and that does in fact have the connotations we want it to have. I like it
> too.
>
> More seriously, this discussion has convinced me that it's worth including
> what the proposal discusses as a *'future' case*. The key point that
> swayed me is that this can produce a *warning* when the switch is missing
> a case rather than an *error,* which both provides the necessary compiler
> feedback to update your code and allows your dependencies to continue
> compiling when you update to a newer SDK. I know people on both sides won't
> be 100% satisfied with this, but does it seem like a reasonable compromise?
>
> The next question is how to spell it. I'm leaning towards `unexpected
> case:`, which (a) is backwards-compatible, and (b) also handles "private
> cases", either the fake kind that you can do in C (as described in the
> proposal), or some real feature we might add to Swift some day. `unknown
> case:` isn't bad either.
>
> I too would like to just do `unknown:` or `unexpected:` but that's
> technically a source-breaking change:
>
> switch foo {
> case bar:
>   unknown:
>   while baz() {
> while garply() {
>   if quux() {
> break unknown
>   }
> }
>   }
> }
>
>
> Another downside of the `unexpected case:` spelling is that it doesn't
> work as part of a larger pattern. I don't have a good answer for that one,
> but perhaps it's acceptable for now.
>
> I'll write up a revision of the proposal soon and make sure the core team
> gets my recommendation when they discuss the results of the review.
>
> ---
>
> I'll respond to a few of the more intricate discussions tomorrow,
> including the syntax of putting a new declaration inside the enum rather
> than outside. Thank you again, everyone, and happy new year!
>
> Jordan
>


+1 to warning instead of error
+1 to unknown/unexpected case
+1 to “@frozen” or any other reasonable spelling, they are all fine by me.

The one remaining problem to solve is making sure multi-module apps can
leave out the unknown/unexpected case on enums from modules which are part
of the app itself and thus cannot be updated independently of it. John
McCall’s version-locking plan sounds promising, though we should explore
the available options before finalizing a course.

Perhaps we need a concept of submodules, or supermodules, or some other way
to demarcate the boundaries of a resilience domain.

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-02 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Jan 2, 2018 at 12:47 AM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:
>
>
> 1) When dealing with independently updated binary packages, your code
> *has* to implement some behavior for unexpected cases if the enum is
> non-exhaustive.  It isn’t acceptable to not handle that case, and it isn’t
> acceptable to abort because then your app will start crashing when a new OS
> comes out. You have to build some sort of fallback into your app.
>

Yes, absolutely.



> 2) When dealing with a source package that contributes to your app (e.g.
> through SwiftPM), *YOU* control when you update that package, and therefore
> it is entirely reasonable to exhaustively handle enums even if that package
> owner didn’t “intend” for them to be exhaustive.  When *you* chose to
> update the package, you get the “unhandled case” error, and you have
> maximal “knowability” about the package’s behavior.
>

I agree 100%



> It seems that your concern stems from the fact that the feature as
> proposed is aligned around module boundaries, and therefore overly punishes
> source packages like #2.  I hope you agree that in case #1, that the
> feature as proposed is the right and only thing we can do: you really do
> have to handle unknown future cases somehow.
>

I take slight exception to the word “only” here: the proposal as written
does not offer compile-time feedback to inform client programmers that
external enums on which they “switch” have new cases, because they are
required to include a “default” clause.

Yes, those client programmers need to handle unknown cases, but they *also*
deserve the compiler’s assistance in identifying when such cases have been
added. I don’t know if a “future” keyword is the best approach, but we
ought to include some way to warn (not error) when compiling a switch
statement that the author intends to be exhaustive-over-all-known-cases
while also handling unknown ones.



> If I’m getting this right, then maybe there is a variant of the proposal
> that ties the error/warning behavior to whether or not a module is a source
> module vs a binary module.  The problem with that right now is that we have
> no infrastructure in the language to know this…
>
> -Chris
>

If we can make that work, this proposal will be much more palatable.

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-21 Thread Nevin Brackett-Rozinsky via swift-evolution
Making enums non-exhaustive solves a problem for authors of precompiled
frameworks which apps can dynamically link against. These libraries need to
preserve binary compatibility, in the sense that apps should continue to
work with newer versions of the library.

Now, that creates a problem for app developers, wherein the compiler no
longer informs them when their switch statements don’t cover all known enum
cases. This can be solved by introducing “future” for switch statements,
which acts like “default” but will warn if it is provably reachable.

Perhaps the most common scenario, however, is developers who write
multi-module apps. Such apps could include modules with the same author,
modules included as source, and even precompiled binary modules. As long as
these are all bundled with the app, they cannot possibly change out from
under it at runtime, so binary-compatibility is not a concern.

I think it is important that any solution to the problems of dynamically
linked libraries should not adversely impact authors of multi-module apps.

It sounds like John McCall has an approach to handle this with version
locking of dependencies.

Another possibility is to say that public enums are non-exhaustive by
default if the module is built with resilience enabled, but if resilience
is not enabled then enums are exhaustive.

Alternatively, we could introduce a concept of “the entire thing I am
building, including all its statically-linked modules”, and let enums be
exhaustive within that domain while still defaulting to non-exhaustive
outside it.

I am glad to see vigorous debate and brainstorming on this thread, and I am
confident that we will find a good solution.

Nevin



On Thu, Dec 21, 2017 at 2:26 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Dec 21, 2017, at 2:03 PM, Jordan Rose via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
> On Dec 20, 2017, at 12:35, Karl Wagner  wrote:
>
>
>
> On 20. Dec 2017, at 19:54, Jordan Rose  wrote:
>
>
>
> On Dec 20, 2017, at 05:36, Karl Wagner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
>
> On 19. Dec 2017, at 23:58, Ted Kremenek via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs through 
> *January
> 3, 2018*.
>
> The proposal is available here:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0192-non-exhaustive-enums.md
>
> +1, it needs to happen (and ASAP, since it _will_ introduce
> source-breaking changes one way or the other).
>
> I think non-exhaustive is the correct default. However, does this not mean
> that, by default, enums will be boxed because the receiver doesn’t know
> their potential size?
>
>
> It's not always boxing, but yes, there will be more indirection if the
> *compiler* can't see the contents of the enum. (More on that below.)
>
>
> That would mean that the best transition path for multi-module Apps would
> be to make your enums @exhaustive, rather than adding “default” statements
> (which is unfortunate, because I imagine when this change hits, the way
> you’ll notice will be complaints about missing “default” statements).
>
>
> Yep, that's going to be the recommendation. The current minimal-for-review
> implementation does not do this but I'd like to figure out how to improve
> that; at the very least it might be a sensible thing to do in the migrator.
>
>
> I do have some thoughts about how we could ease the transition (for this
> and other resilience-related changes), but it’s best to leave that to a
> separate discussion.
>
> The one thing I’m still not overly fond of is the name - I would like us
> to keep the set of resilience/optimisation related keywords to a minimum.
> “exhaustive” for enums feels an awful lot like “fixed_contents” for structs
> - couldn’t we come up with a single name which could be used for both? I
> don’t think anybody’s going to want to use “exhaustive” for structs.
>
>
> The core team was very focused on this too, but I contend that
> "exhaustive" is not about optimization and really isn't even about
> "resilience" (i.e. the ability to evolve a library's API while preserving
> binary compatibility). It's a semantic feature of an enum, much like 'open'
> or 'final' is for classes, and it affects what a client can or can't do
> with an enum. For libaries compiled from source, it won't affect
> performance at all—the *compiler* still knows the full set of cases in the
>  *current* version of the library even if the programmer is forced to
> consider future versions.
>
> I'm working on the fixed-contents proposal now, though it won't be ready
> for a while, and the same thing applies there: for structs compiled from
> source, the compiler can still do all the same optimizations. It's only
> when the library has binary compatibility concerns that we need to use
> extra indirection, and then "fixed-contents" becomes important. (As
> currently designed, it does

Re: [swift-evolution] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-20 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Dec 20, 2017 at 10:01 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:
>
> I have been doing the unkosher thing of using these underscored attributes
> and would very much like to see these formalized.
>
> My one bikeshedding issue here is the name @abiPublic, which smells too
> much like fileprivate in my subjective opinion. A more concrete objection
> here is the very much non-ideal juxtaposition of two different access
> modifier terms in the "@abiPublic internal" spelling. It would seem to me
> that "@abi" would suffice instead. Indeed, the fact that it's an
> "interface" implies a certain level of visibility, which in my view is more
> precise than coopting the term "public"--that term in turn has an
> established meaning in Swift that, by construction, an "@abiPublic
> internal" method does not fulfill.
>

Alternatively, since the “@abiPublic” attribute allows objects to be used
by inlined code, why not spell it “@inlinable”?

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


Re: [swift-evolution] [swift-evolution-announce] [Accepted with revisions] SE-0187 “Introduce Sequence.filterMap(_:)”

2017-12-19 Thread Nevin Brackett-Rozinsky via swift-evolution
If we’re bikeshedding the verb tense then “compactMap” sounds right to me,
and adding “ing” would be needlessly verbose.

For the non-mapping version, I’d lean toward “compacted”. However, we could
also postpone the debate over its spelling until such time as we are
actually ready to introduce it.

Nevin



On Tue, Dec 19, 2017 at 6:42 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On Dec 19, 2017, at 2:28 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I disagree. Let’s not reopen what is settled. “Compact” can be a noun just
> as “map” and “filter” can; as long as there are no in-place variants, there
> can be no ambiguity.
> On Tue, Dec 19, 2017 at 17:11 Brent Royal-Gordon via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Dec 19, 2017, at 8:56 AM, John McCall  wrote:
>>
>> Therefore, SE-0187 is *accepted*, with the *revision* that the new name
>> be Sequence.compactMap(_:), and with the agreement that we will add
>> Sequence.compact() when it is possible to do so.
>>
>>
>> I like `compact` as the basis for the name, but I hope the core team will
>> consider whether the eventual nil-removal method should be called
>> `compacting()`, and whether therefore this method should be called
>> `compactingMap(_:)`. Prior art on the name `compact()` does exist, but I
>> don't think it's strong enough to justify deviating from the API Guidelines.
>>
>> I don't think we need a full review on this tiny issue; five minutes of
>> the core team's time should more than suffice.
>>
>
> I agree with Brent. IMO we're firmly outside the domain of established
> terms-of-art here (Ruby notwithstanding).
>
> ___
> 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: Introduce User-defined "Dynamic Member Lookup" Types

2017-12-02 Thread Nevin Brackett-Rozinsky via swift-evolution
I have no input on whether or not this dynamism should be added to Swift.

However, *if* we add it, then I strongly prefer that dynamic member lookup
should use the exact same syntax as static member lookup, namely a single
dot. Member lookup is member lookup, the user-facing behavior is the same
is both cases, and we should present a single coherent experience with
maximum elegance and simplicity.

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


Re: [swift-evolution] [RFC] Associated type inference

2017-12-01 Thread Nevin Brackett-Rozinsky via swift-evolution
On Thu, Nov 30, 2017 at 7:28 PM, Douglas Gregor via swift-evolution <
swift-evolution@swift.org> wrote:

> *A Rough Proposal*
> I’ve been thinking about this for a bit, and I think there are three ways
> in which we should be able to infer an associated type witness:
>
>
>1. Associated type defaults, which are specified with the associated
>type itself, e.g.,
>
>  associatedtype Indices = DefaultIndices
>
>These are easy to reason about for both the programmer and the
>compiler.
>2. Typealiases in (possibly constrained) protocol extensions, e.g.,
>
>  extension RandomAccessCollection where Index : Strideable,
>Index.Stride == IndexDistance {
>typealias RandomAccessCollection.Indices = CountableRange
>  }
>
>I’m intentionally using some odd ‘.’ syntax here to indicate that this
>typealias is intended only to be found when trying to satisfy an associated
>type requirement, and is not a general typealias that could be found by
>normal name lookup. Let’s set the syntax bike shed aside for the moment.
>The primary advantage of this approach (vs. inferring Indices from “var
>Indices: CountableRange” in a constrained protocol extension) is
>that there’s a real typealias declaration that compiler and programmer
>alike can look at and reason about based just on the name “Indices”.
>
>Note that this mechanism technically obviates the need for (1), in the
>same sense that default implementations in protocols
>
> 
>  are
>merely syntactic sugar.
>3. Declarations within the nominal type declaration or extension that
>declares conformance to the protocol in question. This is generally the
>same approach as described in “associated type inference” above, where we
>match requirements of the protocol against declarations that could satisfy
>those requirements and infer associated types from there. However, I want
>to turn it around: instead of starting with the requirements of the
>protocol any looking basically anywhere in the type or any protocol to
>which it conforms (for implementations in protocol extensions), start with
>the declarations that the user explicitly wrote at the point of the
>conformance and look for requirements they might satisfy. For example,
>consider our initial example:
>
>  extension MyCollection: RandomAccessCollection {
>var startIndex: Int { return contents.startIndex }
>var endIndex: Int { return contents.endIndex }
>subscript(index: Int) -> T { return contents[index] }
>  }
>
>Since startIndex, endIndex, and subscript(_:) are declared in the same
>extension that declares conformance to RandomAccessIterator, we should look
>for requirements with the same name as these properties and subscript
>within RandomAccessCollection (or any protocol it inherits) and infer Index
>:= Int and Element := T by matching the type signatures. This is still the
>most magical inference rule, because there is no declaration named “Index”
>or “Element” to look at. However, it is much narrower in scope than the
>current implementation, because it’s only going to reason from the
>(probably small) set of declarations that the user wrote alongside the
>conformance, so it’s more likely to be intentional. Note that this is again
>nudging programmers toward the style of programming where one puts one
>protocol conformance per extension, which is admittedly my personal
>preference.
>
>
> *Thoughts?*
> I think this approach is more predictable and more implementable than the
> current model. I’m curious whether the above makes sense to someone other
> than me, and whether it covers existing use cases well enough. Thoughts?
>
> - Doug
>


How does this work with retroactive conformance, especially where all the
protocol requirements already exist on a type and an empty extension
declares conformance? For example, suppose Module A declares a protocol
with associated types, and Module B has a struct which naturally possesses
all the required members to conform (maybe B handles Double concretely,
while A can work with any FloatingPoint, or some such). As a client
importing both modules and providing an empty extension to conform B’s
struct to A’s protocol, will the associated types be inferred?

Also, have you considered the possibility of allowing protocol authors to
specify which types should be inferred from which requirements? For example
Collection might demarcate “startIndex” as the source-of-truth for
inferring “Index”, and “subscript (Index)->Element” as the source-of-truth
for inferring “Element”.

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


Re: [swift-evolution] [Pitch] Make Optional, Array, and Dictionary conditionally Equatable

2017-11-28 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Nov 28, 2017 at 1:05 PM, Douglas Gregor via swift-evolution <
swift-evolution@swift.org> wrote:

>
> To close the loop here, the core team has agreed to this as an amendment
> to SE-0143, and the changed has been merged here:
>
> https://github.com/apple/swift-evolution/pull/769
>
> and we’ve merged the change into the Swift standard library for Swift 4.1,
> here:
>
> https://github.com/apple/swift/pull/13046
>
> - Doug
>


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


Re: [swift-evolution] [Review] SE-0191: Eliminate IndexDistance from Collection

2017-11-27 Thread Nevin Brackett-Rozinsky via swift-evolution
The proposal mentions one reasonable situation where a larger-than-Int type
would be useful, namely a Collection wrapping a memory-mapped file, being
used on 32-bit systems.

Is there a recommended migration strategy for this scenario?

Nevin


On Mon, Nov 27, 2017 at 8:34 PM, Douglas Gregor via swift-evolution <
swift-evolution@swift.org> wrote:

> Hello Swift community,
>
> The review of SE-0191 "Eliminate IndexDistance from Collection" begins now
> and runs through December 3, 2017. The proposal is available here:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0191-eliminate-indexdistance.md
>
> Reviews are an important part of the Swift evolution process. All reviews
> should be sent to the swift-evolution mailing list at
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> or, if you would like to keep your feedback private, directly to the
> review manager. When replying, please try to keep the proposal link at the
> top of the message:
>
> Proposal link:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0191-eliminate-indexdistance.md
>
> Reply text
>
> Other replies
>
> What
> goes into a review?
>
> The goal of the review process is to improve the proposal under review
> through constructive criticism and, eventually, determine the direction of
> Swift. When writing your review, here are some questions you might want to
> answer in your review:
>
>- What is your evaluation of the proposal?
>- Is the problem being addressed significant enough to warrant a
>change to Swift?
>- Does this proposal fit well with the feel and direction of Swift?
>- If you have used other languages or libraries with a similar
>feature, how do you feel that this proposal compares to those?
>- How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>
> More information about the Swift evolution process is available at
>
> https://github.com/apple/swift-evolution/blob/master/process.md
>
> Thank you,
>
> -Doug
>
> Review Manager
>
> ___
> 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] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-15 Thread Nevin Brackett-Rozinsky via swift-evolution
Without commenting on anything else, I have encountered one use-case where
it would be nice to be able to “call” an instance. And that is, while
modeling some mathematics, I made a DifferentiableFunction type which
stores a function and optionally a reference to another
DifferentiableFunction (its derivative).

I used the subscript notation for “calling” these DifferentiableFunctions,
because that’s what we have available, but it would certainly be nice to
use parentheses rather than square brackets.

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


Re: [swift-evolution] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Nov 15, 2017 at 8:05 PM, Wallacy via swift-evolution <
swift-evolution@swift.org> wrote:

> “unwrappingMap”(or some variations using unwrap).
>

 I’d like to propose “mapAndUnwrap”.

It does what it says on the tin: map a sequence (into an optional type),
then unwrap the values which exist.

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


Re: [swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sun, Nov 12, 2017 at 10:16 PM, Slava Pestov  wrote:
>
> Pardon my lack of imagination, but could you provide an example of a call
> site that would become ambiguous?
>
>
> protocol P {}
> protocol Q {}
> struct S : P, Q {}
>
> struct Outer {
>   static func foo(_: P) {}
>
>   struct Inner {
> static func foo(_: Q) {}
>
> static func bar() {
>foo(S())
> }
>   }
> }
>

Resolves to Inner.foo just like it does today.

We would still start from the innermost scope and work our way outward
until we find a match. The only difference is we no longer stop partway up
the chain *without* finding a match.

If we do find a match then yes, of course we stop there and use it.

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


Re: [swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sun, Nov 12, 2017 at 8:44 PM, Slava Pestov  wrote:

> Yeah, this is an unfortunate wart. Right now unqualified lookup starts at
> the innermost scope and stops when it finds a candidate which matches the
> name being looked up. Overload sets are only formed if there are multiple
> candidates inside the same scope, not in different scopes.
>
> It would be nice to fix this but note that it might have a compile-time
> performance impact, because now we will be looking up names in more scopes.
> In particular, this means almost every name lookup will have to look at all
> imported modules.
>

Well, the fact that it currently gives a different error message if you
delete the global function, tells me that *something* in the compiler is
already looking at both the member function and the global function.



> If this can be implemented in a clever way without impacting compile time,
> I’ll be all for this change.
>
> However, note that the most common way in which people hit this is with
> type(of:) vs a local name named type — I think this can be solved without
> fundamentally changing unqualified lookup, by having unqualified lookup
> look at the DeclName rather than an Identifier. So if you have
>
> var type = …
>
> type(of: foo)
>
> We would not consider the ‘var type’ at all, since it doesn’t match the
> DeclName type(of:). This might also address min vs Collection.min if we
> consider the number of arguments when performing the lookup too.
>
> Either way I think an evolution proposal is a good idea, this has source
> compatibility impact since it can introduce ambiguity at call sites that
> were formerly unambiguous. But we should be careful not to impact compile
> time.
>

Pardon my lack of imagination, but could you provide an example of a call
site that would become ambiguous?

The change I am proposing has the effect of taking something that is
currently a compiler error (calling a global function when a member
function has the same base name but a different signature) and making it
not-an-error (since the global function is the only one whose signature
matches the call site).

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


[swift-evolution] When exactly 1 function matches a call site, should it be called or cause a compiler error?

2017-11-12 Thread Nevin Brackett-Rozinsky via swift-evolution
I brought this up on Swift Dev and was told to check on Swift Evolution to
see if a proposal is needed.

Currently, the following code produces a compiler error:

func foo(_ x: Int, _ y: Int) -> Int {
  return x + y
}

extension Int {
  func foo() -> Int {
return foo(self, self)// Error here
  }
}

Notice that the two functions named “foo” have entirely different
signatures. The global function takes 2 arguments, while the member
function takes 0 (or 1, if referenced as “Int.foo”).

There is exactly one function “foo” which takes 2 arguments, so a call to
“foo” with 2 arguments, like the one shown, should be unambiguous. However,
instead of calling the function with matching signature, there is instead a
compiler error.

This is already documented as SR–2450
, with an example from the standard
library (global 2-argument “min” vs. 0-argument “Collection.min”).

It appears that in any situation where a global function and a member
function share the same base name, but only the global function’s signature
matches the call site, the result is a compiler error.

I suggest that, when there is exactly one function available with the
proper name and signature, instead of a compiler error the
matching function should be called.

Do we need a Swift Evolution proposal for this change?

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


Re: [swift-evolution] SE-1084 (B): buffer pointer partial initialization API

2017-10-11 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wednesday, October 11, 2017, Kelvin Ma via swift-evolution <
swift-evolution@swift.org> wrote:

> Yes, a 0-ary operator like that would have to be hard baked into the
> language itself.
>

Actually, you can just make a subscript which takes a function as an
argument, and call it by passing in the ellipsis operator.

Nevin


 Of course, the subscript notation has much more serious problems, there is
> no way to allow one-sided subscripting, but disallow two-sided subscripting
> for the memory API, while still allowing two-sided subscripting for
> ordinary slicing operations. This is why I still think at:from: is the
> much better syntax.
>
> On Wed, Oct 11, 2017 at 3:01 PM, Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com
> > wrote:
>
>> I believe Kelvin was asking about the usage of ellipsis *by itself*, as
>> in Xiaodi’s example, “newBuffer[...]”.
>>
>> Nevin
>>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] SE-1084 (B): buffer pointer partial initialization API

2017-10-11 Thread Nevin Brackett-Rozinsky via swift-evolution
I believe Kelvin was asking about the usage of ellipsis *by itself*, as in
Xiaodi’s example, “newBuffer[...]”.

Nevin


On Wed, Oct 11, 2017 at 2:42 PM, Anders Ha via swift-evolution <
swift-evolution@swift.org> wrote:

> ICYMI, SE-0172 was the proposal of one sided range and it has been
> implemented as part of 4.0.
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0172-one-sided-ranges.md
>
>
> Regards
> Anders
>
> > On 11 Oct 2017, at 4:43 AM, Kelvin Ma via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >
> >
> > On Tue, Oct 10, 2017 at 1:00 AM, Xiaodi Wu  wrote:
> > On Mon, Oct 9, 2017 at 19:47 Kelvin Ma via swift-evolution <
> swift-evolution@swift.org> wrote:
> > Hi guys, after passing SE 184 (A), I want to get some community feedback
> on the next phase of our Swift pointer overhaul which is a partial
> initialization/deinitialization API for UnsafeMutableBufferPointer and
> UnsafeMutableRawBufferPointer.
> >
> > You can read about the originally proposed API in the original SE 184
> document, basically we use an at:from: system for binary memory state
> operations where the at: argument supplies the start position in the
> destination buffer, and the from: source argument supplies the number of
> elements to copy/move into the destination.
> >
> > newBuffer.moveInitialize(at: 0, from: self.buffer[self.zero... ])
> > newBuffer.moveInitialize(at: self.zero, from: self.buffer[0 ..<
> self.zero])
> >
> > Some other proposed APIs include using subscript notation, and writing a
> special buffer slice type and a corresponding protocol to handle this.
> >
> > newBuffer[0...].moveInitialize(from:
> self.buffer[self.zero...   ])
> > newBuffer[self.zero ... self.zero << 1].moveInitialize(from:
> self.buffer[0 ..< self.zero])
> >
> > Fully embracing slice notation and SwiftLint style, this could be:
> >
> > newBuffer[...].moveInitialize(from: buffer[zero...])
> > newBuffer[zero...].moveInitialize(from: buffer[.. >
> > Is the solo ellipsis operator even valid Swift syntax? And I agree this
> would look nice, but as others have mentioned, Swift has the convention
> that the one-sided slice operators are equivalent to start ... endIndex and
> startIndex ... end. And that seems to strongly suggest that the method
> would initialize the entire range which is not what we want to communicate.
> >
> >
> > A hypothetical comparison of this API, the at:from: API, and the
> existing plain pointer API can be found in this basic Swift queue
> implementation here if anyone wants to see how this would look in “real”
> code. I’m interested in seeing which syntax and which API is preferred as
> well as what people would like to do with an expanded Swift buffer pointer
> toolbox.
> >
> > Would you mind rewriting these examples in a more common Swift style
> (for instance, SwiftLint/GitHub style)? Everyone is entitled to write code
> how they please, but it’s much easier to compare how things “look” when the
> overall formatting is more familiar.
> >
> > I mean the purpose of the example is to compare the call sites of the
> actual buffer methods. ignoring the function signatures and instead getting
> distracted by brace placement seems like the kind of bikeshedding we should
> be discouraging lol.
> >
> >
> >
> > ___
> > 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] Fix "private extension" (was "Public Access Modifier Respected in Type Definition")

2017-10-07 Thread Nevin Brackett-Rozinsky via swift-evolution
Two weeks ago I had a fairly strong opinion about “private extension”
behavior. After following this discussion, I now have no opinion on the
matter.

I would summarize the points on both sides as follows:

For the change:
• It is surprising to many people that members of a private extension are
implicitly fileprivate.
• There is currently no way to make an extension whose members default to
private.

Against the change:
• The proposal is source-breaking.
• The proposal makes “fileprivate” more common.
• A private extension and a (top-level) private type both currently have
implicitly fileprivate members. The proposal breaks that symmetry.

Notable questions:
• Currently “open” cannot be applied to an extension at all, should we
allow it?
• Might we ever want to allow nested (non-top level) extensions, and if so
how should access levels on them work?

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


Re: [swift-evolution] Property Getter Return Statement

2017-10-07 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sat, Oct 7, 2017 at 11:24 AM, Xiaodi Wu  wrote:

> This has been brought up on the list before. For instance:
>
> https://github.com/apple/swift-evolution/pull/608
>
> Chris Lattner’s response at that time was:
>
> ‘Just MHO, but I consider this syntactic sugar, not a fundamental feature
> that fits the goal of Swift 4 stage 2.
>
> ‘I’m also pretty opposed to doing it at any time. The rationale of
> “implicit return” in closures is specifically because they are limited to a
> single expression, which makes the semantics “obvious”. This was carefully
> considered.’


This objection is not applicable, because we are discussing the possibility
to omit “return” exactly when there is a single expression in the getter.

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


Re: [swift-evolution] Property Getter Return Statement

2017-10-07 Thread Nevin Brackett-Rozinsky via swift-evolution
+1

We don’t need “return” in single-line closures where the type is known, and
I don’t see why it is required in single-line getters.

Nevin


On Sat, Oct 7, 2017 at 10:07 AM, James Valaitis via swift-evolution <
swift-evolution@swift.org> wrote:

> Is it widely agreed that it is necessary to require a return statement on
> a one line property getter?
>
> var session: AVCaptureSession { get { return layer.session } }
>
> Or could we follow the convention for any other close and get rid of it?
> For me it seems redundant; the word `get` literally precedes the closure.
> ___
> 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] superscripts, subscripts, etc.

2017-10-05 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Oct 3, 2017 at 2:02 AM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

> You want:
>
> x²  to parse as “superscript2(x)” - not as an identifier “xsuperscript2”
> which is distinct from x.
>
> -Chris


I am of two minds on this. Sometimes I want x² to parse as x*x (an
operator) but other times I want to store the value of x*x in an identifier
spelled… x². This could be simply to avoid repeatedly performing the same
calculation, or it could be the natural result as in,

let r² = someStatisticsThing(xVals, yVals)

Not sure where I’m going with this, just wanted to mention it.

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


Re: [swift-evolution] Pitch: Cross-module inlining and specialization

2017-10-04 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Oct 2, 2017 at 5:45 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> This is unduly restrictive; @_versioned (despite being the wrong spelling)
> is what we want here. To be callable from an inlinable function, internal
> things need only be visible in terms of public ABI, not necessarily
> inlinable, just as public things need only be public and not necessarily
> inlinable.
>

Unduly restrictive is fine for now, we don’t need to make @_versioned ready
for primetime just to roll out @inlinable. We can begin with the semantics
that @inlinable functions can only call things which are themselves either
@inlinable or public, and then subsequently in the future we can expand it
to “…or whatever-we-end-up-calling-@_versioned”.

That way the scope of this proposal can stay narrow and self-contained.

Nevin



> On Mon, Oct 2, 2017 at 16:37 Nevin Brackett-Rozinsky via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Mon, Oct 2, 2017 at 5:21 PM, Slava Pestov  wrote:
>>
>>> Thanks for taking a look!
>>>
>>> > On Oct 2, 2017, at 2:19 PM, Nevin Brackett-Rozinsky <
>>> nevin.brackettrozin...@gmail.com> wrote:
>>> > 3. Even though @inlinable will have no effect on declarations which
>>> are not public, we should still allow it to be placed there. That way when
>>> the access level is later changed to be public, the attribute is already
>>> where it should be. This is similar to why we permit, eg., members of an
>>> internal type to be declared public, which was discussed and decided
>>> previously on Swift Evolution.
>>>
>>> This is an interesting point. Do you think the attribute should be
>>> completely ignored, or should the restrictions on references to non-public
>>> things, etc still be enforced?
>>>
>>
>>  Hmm, good question!
>>
>> I rather like the idea Greg Parker put forth, where non-public @inlinable
>> items can be used by public @inlinable ones, which implies that the
>> restrictions should indeed still apply—something @inlinable can only
>> reference public or @inlinable things.
>>
>> Nevin
>> ___
>> 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] [Generics] [Pitch] Dependent Types

2017-10-02 Thread Nevin Brackett-Rozinsky via swift-evolution
I rather suspect that we would be best served by starting with integer
literals as the only accepted “values in generics”. This would let us
define fixed-size arrays and matrices, the modular arithmetic types you
describe, and several other mathematical entities.

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


Re: [swift-evolution] Pitch: Cross-module inlining and specialization

2017-10-02 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Oct 2, 2017 at 5:21 PM, Slava Pestov  wrote:

> Thanks for taking a look!
>
> > On Oct 2, 2017, at 2:19 PM, Nevin Brackett-Rozinsky <
> nevin.brackettrozin...@gmail.com> wrote:
> > 3. Even though @inlinable will have no effect on declarations which are
> not public, we should still allow it to be placed there. That way when the
> access level is later changed to be public, the attribute is already where
> it should be. This is similar to why we permit, eg., members of an internal
> type to be declared public, which was discussed and decided previously on
> Swift Evolution.
>
> This is an interesting point. Do you think the attribute should be
> completely ignored, or should the restrictions on references to non-public
> things, etc still be enforced?
>

 Hmm, good question!

I rather like the idea Greg Parker put forth, where non-public @inlinable
items can be used by public @inlinable ones, which implies that the
restrictions should indeed still apply—something @inlinable can only
reference public or @inlinable things.

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


Re: [swift-evolution] Pitch: Cross-module inlining and specialization

2017-10-02 Thread Nevin Brackett-Rozinsky via swift-evolution
I am hugely in favor of an @inlinable attribute, and I look forward to its
arrival with relish!

Some feedback:

1. I think “inlinable” is the right spelling: it indicates that something
is *able* to be inlined.

2. If I want to pass an @inlinable function as an argument (say, to map or
filter) can I do so directly or must I use a closure which calls the
inlinable function?

3. Even though @inlinable will have no effect on declarations which are not
public, we should still allow it to be placed there. That way when the
access level is later changed to be public, the attribute is already where
it should be. This is similar to why we permit, eg., members of an internal
type to be declared public, which was discussed and decided previously on
Swift Evolution.

Other than that the proposal looks great, thanks for writing it up.

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


Re: [swift-evolution] Re-pitch: remove(where:)

2017-09-26 Thread Nevin Brackett-Rozinsky via swift-evolution
I think it is worth considering a version which both removes items in
place, and also returns the removed items, so as to split the collection by
a predicate.

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


[swift-evolution] Retroactive protocol inheritance

2017-09-22 Thread Nevin Brackett-Rozinsky via swift-evolution
With Swift 4 out, I’ve started using the numeric protocols quite a bit, and
they are great!

One thing I find myself wishing for is a protocol that extends Numeric
while also allowing division—a Field protocol, if you will. I have
implemented several algorithms generically over FloatingPoint because they
need division, which means they aren’t available for, eg., a Rational type.

Absent a Field protocol in the standard library, I can create one of my own:

protocol Field: Numeric {
  static func / (lhs: Self, rhs: Self) -> Self
}

And I can extend Float and Double and Float80 to conform easily enough.
However, I’d really like to write,

extension FloatingPoint: Field {}

and make every type which conforms to FloatingPoint (such as a third-party
Complex type), also conform to Field.

Is this potentially feasible? Would other people find it useful?

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


[swift-evolution] Different types for getter and setter

2017-09-19 Thread Nevin Brackett-Rozinsky via swift-evolution
This may sound rather strange in the abstract, but recently I have
encountered two situations where I would like to have a setter that accepts
a different type than the getter returns.

In the first, the getter returns Foo and the setter should accept
“@escaping @autoclosure () -> Foo”, so that the expression assigned to the
property is not evaluated until it is needed. (The closure is stored in a
private property, which the getter evaluates then caches the result.)

In the second, I want a subscript whose getter returns a concrete type (in
my case, subscripting a matrix by row returns an ArraySlice) while
the setter can accept something more generic (any kind of Collection with
the correct Element type).

Thoughts?

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


Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-13 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Sep 13, 2017 at 2:47 PM, Vladimir.S via swift-evolution <
swift-evolution@swift.org> wrote:
>
>
> As was noted in this thread, some people believe that protocol
> synthesizing its requirements by accessing type's fields is of a different
> kind than 'usual' protocol with default implementation.
> I belong to that camp. So, from my point of view, it is important to have
> 'deriving'-like marker for 'auto-senthesizeable' protocols as described
> above.


This is a distinction without a difference
.
Witness:

To the *author* of a type, there is no difference between a default
implementation provided by a protocol extension, and one provided by
compiler magic. In both cases the author simply conforms to the protocol
and their type obtains the default method implementation which they may
choose to override.

To the *maintainer* of a type, there is no difference between the two
possible sources of a default implementation. They see that the type
conforms, and that it does not implement the requirement, so they surmise a
default implementation is in play, which they may choose to override.

To the *user* of a type, there is no difference either. They simply make
use of the existing conformance, which means they can call the methods
defined by the protocol.

The only interested party for whom the distinction is material, is the
author of the protocol itself. And even there, the only difference is that
with compiler magic the default implementation does not need to be written
in a protocol extension.

***

Personally, I am *delighted* at where SE-0185 ended up. It makes simple
cases simple, without changing what needs to be done for complex cases.

If we had been required to write an extra word like “deriving” or “auto”,
that would make declarations for simple types more verbose and ugly, with
no change to the complex case. It would be all cost and no benefit.

The way it is, though, we get both elegance and ease of use. And when we
eventually add the “@transient” attribute, many of the currently-complex
cases will become much simpler. We are in a good place, on the road to a
better place, and the proposed modification in this thread would dig a hole
in the pavement.

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


Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-12 Thread Nevin Brackett-Rozinsky via swift-evolution
Tony makes an excellent point, and I agree. At some point in the future we
should consider introducing a “transient” attribute for caches and other
non-essential properties. That will make generated conformances more
powerful while simultaneously reducing boilerplate.

Nevin


On Tue, Sep 12, 2017 at 10:39 AM, Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On Mon, Sep 11, 2017 at 10:05 PM Gwendal Roué 
> wrote:
>
>>
>> There is this sample code by Thorsten Seitz with a cached property which
>> is quite simple and clear : https://lists.swift.org/
>> pipermail/swift-evolution/Week-of-Mon-20170911/039684.html
>>
>> This is the sample code that had me enter the "worried" camp.'
>>
>
> I really like Thorsten's example, because it actually proves that
> requiring explicit derivation is NOT the correct approach here. (Let's set
> aside the fact that Optionals prevent synthesis because we don't have
> conditional conformances yet, and assume that we've gotten that feature as
> well for the sake of argument.)
>
> Let's look at two scenarios:
>
> 1) Imagine I have a value type with a number of simple Equatable
> properties. In a world where synthesis is explicit, I tell that value type
> to "derive Equatable". Everything is fine. Later, I decide to add some
> cache property like in Thorsten's example, and that property just happens
> to also be Equatable. After doing so, the correct thing to do would be to
> remove the "derive" part and provide my custom implementation. But if I
> forget to do that, the synthesized operator still exists and applies to
> that type. If you're arguing that "derive Equatable" is better because its
> explicitness prevents errors, you must also accept that there are possibly
> just as many cases where that explicitness does *not* prevent errors.
>
> 2) Imagine I have a value type with 10 Equatable properties and one
> caching property that also happens to be Equatable. The solution being
> proposed here says that I'm better off with explicit synthesis because if I
> conform that type to Equatable without "derive", I get an error, and then I
> can provide my own custom implementation. But I have to provide that custom
> implementation *anyway* to ignore the caching property even if we don't
> make synthesis explicit. Making it explicit hasn't saved me any work—it's
> only given me a compiler error for a problem that I already knew I needed
> to resolve. If we tack on Hashable and Codable to that type, then I still
> have to write a significant amount of boilerplate for those custom
> operations. Furthermore, if synthesis is explicit, I have *more* work
> because I have to declare it explicitly even for types where the problem
> above does not occur.
>
> So, making derivation explicit is simply a non-useful dodge that doesn't
> solve the underlying problem, which is this: Swift's type system currently
> does not distinguish between Equatable properties that *do* contribute to
> the "value" of their containing instance vs. Equatable properties that *do
> not* contribute to the "value" of their containing instance. It's the
> difference between behavior based on a type and additional business logic
> implemented on top of those types.
>
> So, what I'm trying to encourage people to see is this: saying "there are
> some cases where synthesis is risky because it's incompatible with certain
> semantics, so let's make it explicit everywhere" is trying to fix the wrong
> problem. What we should be looking at is *"how do we give Swift the
> additional semantic information it needs to make the appropriate decision
> about what to synthesize?"*
>
> That's where concepts like "transient" come in. If I have an
> Equatable/Hashable/Codable type with 10 properties and one cache property,
> I *still* want the synthesis for those first 10 properties. I don't want
> the presence of *one* property to force me to write all of that boilerplate
> myself. I just want to tell the compiler which properties to ignore.
>
> Imagine you're a stranger reading the code to such a type for the first
> time. Which would be easier for you to quickly understand? The version with
> custom implementations of ==, hashValue, init(from:), and encode(to:) all
> covering 10 or more properties that you have to read through to figure out
> what's being ignored (and make sure that the author has done so correctly),
> or the version that conforms to those protocols, does not contain a custom
> implementation, and has each transient property clearly marked? The latter
> is more concise and "transient" carries semantic weight that gets buried in
> a handwritten implementation.
>
> Here's a fun exercise—you can actually write something like "transient"
> without any additional language support today: https://gist.github.com/
> allevato/e1aab2b7b2ced72431c3cf4de71d306d. A big drawback to this
> Transient type is that it's not as easy to use as an Optional because of
> the additional sugar that Swift provides fo

Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-06 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Sep 6, 2017 at 5:42 PM, Haravikk via swift-evolution <
swift-evolution@swift.org> wrote:

> the issue I'm trying to raise is that when those, and similar features,
> are used in synthesised behaviour (default implementations based upon the
> concrete type), that these behaviours should be opted into explicitly,
> otherwise they open up potential for all kinds of bugs, even when the
> assumptions being made about the concrete type are simple such as in the
> case for Equatable/Hashable. There's just too much potential for this kind
> of reflective protocol implementation to overreach; to me it feels very
> much like going into a restaurant and the waiter coming across and
> force-feeding me something I don't want instead of taking my order.
>

I might suggest that instead it is like you have gone into a pizza shop and
said, “I’d like a large veggie pizza please.” And they made you a pizza
with their standard dough and their standard sauce and their standard
cheese and their standard selection of vegetables.

If you wanted some other dough or sauce or cheese or toppings you would
have ordered it. And the fact is you *did* order a veggie pizza (ie.
conformed to a certain protocol). It’s not like they brought you something
you didn’t order. You ordered what you wanted, and that’s what they brought
you.

And for those times when you *do* want to customize your order, that is
perfectly fine too.

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


Re: [swift-evolution] [Accepted] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-17 Thread Nevin Brackett-Rozinsky via swift-evolution
I am really glad this is happening, it will make implementing basic data
types much nicer, and it is exactly the sort of feature that saves
developers from having to waste time thinking about trivial rote
boilerplate both when writing and when reading code—an excellent and
welcome addition to the language.

As for Haravikk’s scenario of marking a type as Equatable to trigger an
error so you remember to implement the protocol later, you can achieve the
same goal by tagging it “MakeMeEquatable” instead. The compiler will give
an error (because there is no such protocol) and then you can come back to
fix it another time.

Nevin


On Wed, Aug 16, 2017 at 6:29 PM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

> Proposal Link: https://github.com/apple/swift-evolution/blob/master/
> proposals/0185-synthesize-equatable-hashable.md
>
> The review of SE-0185 “Synthesizing Equatable and Hashable conformance”
> ran from August 9…15, 2017. Feedback for the feature was glowingly
> positive, and the proposal is accepted.  The core team discussed the
> concerns raised in the feedback thread for the proposal.  Here are some
> rough notes (not intended to be exhaustive), but it is important to
> recognize that the proposal follows the design of the auto-synthesized
> Codable proposal, and that many of these same points were discussed when it
> came up:
>
> - The core team feels that adding compiler magic for this case is
> reasonable because it solves an important user need, and doesn’t preclude
> the introduction of a more general feature (e.g. like a macro system, or
> Rust's ‘deriving’ feature) in the future.  When/if that feature is designed
> and built, the compiler magic can be replaced with standard library magic.
>
> - The hash value of a type is not intended to be stable across rebuilds or
> other changes to the code.  It is ok to change if fields are reordered, the
> standard library changes the hash function, etc.  Tony pointed this out
> on-thread, saying:  The stdlib documentation for hashValue states "Hash
> values are not guaranteed to be equal across different executions of your
> program. Do not save hash values to use during a future execution.”
>
> - The code synthesized is meant to feel like a default implementation that
> you’re getting for free from a (constrained) extension on the protocol.
> This is why conformance to the protocol itself is all that is required, not
> something like “AutoEquatable”.
>
> Many thanks to Tony Allevato for driving forward this proposal.  The patch
> just needs final code review now - I think we’re all looking forward to
> this landing, congrats!
>
> Chris Lattner
> Review Manager
>
>
> ___
> 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] private extension

2017-08-09 Thread Nevin Brackett-Rozinsky via swift-evolution
I counter with the rationale for rejecting SE-0119
,
namely:

The review of "SE-0119: Remove access modifiers from extensions" ran from
> July 12...19. The proposal has been *rejected*.
>
> The majority of the feedback on this proposal was opposed to it, because
> it eliminated the useful ability to apply access control to a batch of
> methods and properties.


In other words, access modifiers are allowed on extensions for the express
purpose of being applied to the members in that extension. The fact that in
one of them currently does something *other* than what it says on the tin
is therefore problematic.

Nevin


On Wed, Aug 9, 2017 at 6:31 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> https://lists.swift.org/pipermail/swift-evolution/
> Week-of-Mon-20170417/035885.html
>
>
> On Wed, Aug 9, 2017 at 17:05 David Hart  wrote:
>
>> Do you a have a link to that discussion?
>>
>>
>> On 10 Aug 2017, at 00:04, Xiaodi Wu  wrote:
>>
>> Agree, but again, I tried, and the answer was no, it’s not considered a
>> bug and cannot be fixed without independent discussion.
>> On Wed, Aug 9, 2017 at 16:51 David Hart  wrote:
>>
>>> The last thing I want is to launch into a new round of discussions. I am
>>> just hoping it can be considered as a straight bug that can be fixed
>>> without any discussion.
>>>
>>>
>>> On 9 Aug 2017, at 23:47, Xiaodi Wu  wrote:
>>>
>>> I brought this up after SE-0169, but it was deemed to be a separate
>>> issue and any further consideration was declined. Let’s not initiate
>>> another round of access control discussions.
>>> On Wed, Aug 9, 2017 at 16:31 David Hart via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 Actually, I think this is this way only as a relic from the original
 private/fileprivate proposal. Swift 3’s private has no meaning as an
 extension modifier, so it was made to alias to fileprivate. But
 since SE-0169 modified private’s meaning so that it would make sense
 as an extension modifier, I think we should fix this.

 On 9 Aug 2017, at 23:22, David Hart via swift-evolution <
 swift-evolution@swift.org> wrote:

 That behaviour was never explicitly mentioned in SE-0169 but I agree
 its confusing. But I’m also fairly sure the only window to do anything
 about it is Swift 4. Everybody is really worn down by those access level
 discussions.

 For illustration, Vladimir is confused that:

 private extension Foo {
 func foo() {}
 }

 is equivalent to:

 fileprivate extension Foo {
 func foo() {}
 }

 making it accessible to another type in the same file:

 struct Bar {
 func bar(foo: Foo) {
 foo.foo()
 }
 }

 Aren't access levels on extensions supposed to define the default
 access level of the members of the extension?Is this a bug then?

 On 9 Aug 2017, at 21:18, Vladimir.S via swift-evolution <
 swift-evolution@swift.org> wrote:

 Could someone remind please, was it decided to stick with 'private
 extension' means actually fileprivate access level for members declared in
 such extension or this could be discussed for Swift5?

 Currently, when private members are visible in type/extensions of that
 type in the same file, IMO there is no sense to treat 'private extension'
 as 'fileprivate extension', it is reasonable to group some private members
 of type into extension without making them fileprivate, and such members
 can be used from the type/other extensions.

 And also this is a huge inconsistency in my opinion: all other access
 modifiers 'work' as expected for extensions, but only 'private extension'
 means not what written, very surprising for one who don't expect this.
 ___
 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
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] private extension

2017-08-09 Thread Nevin Brackett-Rozinsky via swift-evolution
I agree this should be considered a simple bug. Have you filed a bug report?

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


Re: [swift-evolution] [Proposal] Synthesizing Equatable/Hashable conformance for enums and structs

2017-08-09 Thread Nevin Brackett-Rozinsky via swift-evolution
Looks good to me, though I have some clarifying questions. For a type which
conforms to both Equatable and Hashable:

1. To automatically derive both Equatable and Hashable, will it be
sufficient to declare “struct Foo: Hashable” (since Hashable refines
Equatable) or must “Equatable” also be listed?

2. Will it be possible to automatically derive “==” while manually
implementing “hashValue”?
2a. If so, will “Equatable” and “Hashable” both need to appear in the
declaration, or will “Hashable” alone suffice?

3. Will it be possible to automatically derive “hashValue” while manually
implementing “==”?
3a. If so, will “Equatable” and “Hashable” both need to appear in the
declaration, or will “Hashable” alone suffice?

Thanks,

Nevin


On Wed, Aug 9, 2017 at 11:36 AM, Tony Allevato via swift-evolution <
swift-evolution@swift.org> wrote:

> Now that Swift 5 is taking proposals, I'm dusting off my proposal to
> synthesize Equatable/Hashable conformance for enums and structs. I had
> implemented this a few months ago hoping to squeeze it in by the Swift 4
> deadline, but unfortunately the timeline was too tight.
>
> The pull request for the proposal is here: https://github.com/
> apple/swift-evolution/pull/706. (Direct link to proposal text:
> https://github.com/allevato/swift-evolution/blob/
> b3dcffc2e6f74e17eba05a6eb7eb29ad58bf36a3/proposals/-
> synthesize-equatable-hashable.md)
>
> The pull request for the implementation (rebased last night) is here:
> https://github.com/apple/swift/pull/9619
>
> Thanks all!
>
>
> ___
> 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] [Pitch] New Version of Array Proposal

2017-07-23 Thread Nevin Brackett-Rozinsky via swift-evolution
I think fixed-size arrays should be a nominal type like any other. They
should be able to have methods, conform to protocols, be extended with new
behavior, and generally present a user-experience similar to what arrays
already have. In particular, they should conform to Collection and to
ExpressibleByArrayLiteral.

If we are going to use semicolons at all, it should be to demarcate the
rows of a 2-dimensional array, as that will be one of the most common
use-cases:

let identity3x3: [Int(3, 3)] = [1, 0, 0;
0, 1, 0;
0, 0, 1]

I also think Chris Lattner has a very good plan for initializing fixed-size
arrays, which I will quote here:

On Sat, Jul 22, 2017 at 3:02 PM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

>
> 1) Fixed size arrays should have an initializer to init all the elements
> to some concrete value.
> 2) They should have an init that takes a closure, and runs it once per
> element, passing in the index.
> 3) Either through a magic value or a third initializer, it should be
> possible to *explicitly* create a fixed size array with uninitialized
> garbage for the elements.  This is important for specific optimizations,
> and should also come to Array as well.
>
> IMO, it isn’t a problem that C allows arrays to be uninitialized - the
> problem is that it is a really bad default.
>
> -Chris


After all, Swift is safe by default, and users can opt into unsafe
territory when necessary. There are certain algorithms which involve
filling in an array of known length in arbitrary order, and they should be
possible to implement in Swift.

There is still the matter of bikeshedding how to spell the type of a
fixed-size array. I used “[Int(3, 3)]” above, but I am nearly certain that
a better spelling exists.

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


Re: [swift-evolution] [swift-evolution-announce] Revision review: SE-104: Protocol-oriented integers

2017-07-21 Thread Nevin Brackett-Rozinsky via swift-evolution
The updates look fine and reasonable to me.

That said, I think it is highly important that we have clarity regarding
what *is* the proper time, method, and process for raising issues with and
suggesting modifications to approved proposals. If there is one thing we
have learned recently it is that sometimes a proposed change sounds good
and gets approved (110, 25, etc.) which subsequently turns out to have
unintended detrimental consequences.

We are not infallible, and there will certainly be times in the future when
we think a change is good in theory, but then after experiencing it in
practice we recognize it has problems. When that happens—and happen it
will—we need to be able to correct our course. And it is far better to fix
such things before they are released to the wider world.

I don’t know if the issues Howard raises rise to that level. I haven’t
tested out the new integer protocols, so I am not in a position to weigh
the merits of the claim. Certainly in the abstract “signum” sounds like it
is asking for a property of the number, and not asking the number to do
something function-like, but I defer to those who use it in practice.

The point is, rather than shutting down discussion by saying “it has
already been approved” and “this is not the place for discussing that”, it
would greatly behoove the Swift Evolution process to have an established
method for recommending changes to already-approved proposals. We have this
time interval between when a proposal is accepted and when it appears in a
public release of the language, and it seems only natural to use it as a
beta-testing period.

That way we can fix problems we encounter before they become permanent, and
similarly we can make minor changes which are obvious improvements we
somehow overlooked during the initial review.

Nevin


On Fri, Jul 21, 2017 at 7:50 AM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> I understand you feel this way, but this thread is a formal review of
> specific amendments to SE-0104. Those amendments are, again, the following:
>
> * Reorganizing shift operators
> * Removing the ArithmeticOverflow type in favor of using a simple Bool
> * Changing BinaryInteger's initializers that convert from floating point
> values
> * Renaming BinaryInteger's init(extendingOrTruncating:)
>
> On Fri, Jul 21, 2017 at 02:08 Haravikk via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> On 21 Jul 2017, at 02:01, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi Howard,
>>
>> The removal of BitwiseOperations is not under review here; that, like
>> signum(), has been considered twice and approved twice, and has not been
>> revised.
>>
>> On Thu, Jul 20, 2017 at 19:36 Howard Lovatt via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> The revised version of the proposal can be found here:
 https://github.com/apple/swift-evolution/blob/master/
 proposals/0104-improved-integers.md

 • What is your evaluation of the proposal?

>>>
>>> Overall +1. Two reservations:
>>>
>>>   1. Functions like `signum()` that return a property would read better
>>> as a property!
>>>   2. I have found `BitwiseOperations` useful as an extension to both
>>> Bool and Set and for a custom set type. Therefore would prefer its
>>> retention and even more preferably that Bool and Set implement it.
>>>
>>> • Is the problem being addressed significant enough to warrant a change
 to Swift?

>>>
>>> Yes, generic representation of integers is useful.
>>>
>>>
 • Does this proposal fit well with the feel and direction of Swift?

>>>
>>> Yes, particularly the re-arrangment of the protocol hierarchy is in
>>> keeping with the rest of the restructuring of the standard library.
>>>
>>>
 • If you have used other languages or libraries with a similar feature,
 how do you feel that this proposal compares to those?

>>>
>>> Yes, many languages I use allow generic numeric functions to be written
>>> and I write my own numeric functions and will therefore use these protocols.
>>>
>>>
 • How much effort did you put into your review? A glance, a quick
 reading, or an in-depth study?

>>>
>>> Quick read, but have pulled my hair out trying to write generic stuff in
>>> Swift as it stands now.
>>>
>>
>> I agree with Howard on both points; In particular I've never agreed with
>> the removal of BitwiseOperations, and believe it to be a mistake. What's
>> the point of making Integers more protocol-oriented if you then go about
>> getting rid of useful protocols?
>> ___
>> 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-ev

Re: [swift-evolution] [pitch] composition as part of the language

2017-06-23 Thread Nevin Brackett-Rozinsky via swift-evolution
This sounds similar to automatic protocol forward, have you looked into
prior discussions on that topic here?

Nevin


On Thu, Jun 22, 2017 at 10:56 PM, Jay Abbott via swift-evolution <
swift-evolution@swift.org> wrote:

> Let's take a quick look at how we can achieve very simple compile-time
> composition in Swift today.
>
> I want to define a `Doorman` behaviour, and I want to compose it from
> other behaviours that are shared by some of my other staff types:
>
> ```swift
> protocol Greeter {
> func greet()
> }
> protocol Fareweller {
> func farewell()
> }
> protocol Doorman: Greeter, Fareweller {}
> ```
>
> Great - that's my interface defined, now some implementations that I can
> compose my staff from:
>
> ```swift
> protocol FriendlyGreeter: Greeter {}
> extension FriendlyGreeter {
> func greet() {
> print("Hello and welcome")
> }
> }
>
> protocol FriendlyFareweller: Fareweller {}
> extension FriendlyFareweller {
> func farewell() {
> print("I bid thee farewell")
> }
> }
>
> protocol InsultingGreeter: Greeter {}
> extension InsultingGreeter {
> func greet() {
> print("You make me sick")
> }
> }
>
> protocol InsultingFareweller: Fareweller {}
> extension InsultingFareweller {
> func farewell() {
> print("Get lost")
> }
> }
> ```
>
> Now we have two kinds of `Greeter` and two kinds of `Fareweller` that can
> be used to compose different `Doorman` types (and potentially other staff
> types). Here's two examples:
>
> ```swift
> struct FriendlyDoorman: Doorman, FriendlyGreeter, FriendlyFareweller {}
> struct TrickingDoorman: Doorman, FriendlyGreeter, InsultingFareweller {}
> ```
>
> I can instantiate and make use of these to perform their defined
> behaviours:
>
> ```swift
> let friendly: Doorman = FriendlyDoorman()
> let tricking: Doorman = TrickingDoorman()
> friendly.greet() // Hello and welcome
> friendly.farewell() // I bid thee farewell
> tricking.greet() // Hello and welcome
> tricking.farewell() // Get lost
> ```
>
> It works! But there are some things that could be nicer:
> * I don't really want `***Greeter` or `***Fareweller` to be sub-protocols
> at all, these are supposed to be implementations - the only reason they are
> protocols is so I can extend them with a default implementation and then
> use more than one of them to compose my actual `Doorman` types. This
> clutters up the namespace with unnecessary protocols, that have the same
> interface as their parent.
> * Since the `***Doorman` types need to be instantiable, they are structs.
> I couldn't compose a `LobbyMultiTasker` from a `FriendlyDoorman` and a
> `GrumpyPorter` at compile-time, the same easy way I composed the
> `***Doorman` types. The manual solution would be to add properties for
> `doormanDelegate` and `porterDelegate` and assign appropriate instances
> (run-time composition), then add the boiler-plate to pass on the
> `LobbyMultiTasker` behaviour to these delegates. This is also how the
> compiler could implement this feature.
> * Actually providing the implementations is optional for the protocols
> (the extensions can happily be missing), meaning any error messages will
> appear in the types that fail to fully implement the protocols, instead of
> here in my `***Greeter` implementation.
>
> So I'd like to discuss the possibility of a new category of types called
> `component`, to allow compile-time composition; composition as part of the
> language. The `***Greeter` and `***Fareweller` might look like this:
>
> ```swift
> component FriendlyGreeter: Greeter {
> func greet() {
> print("Hello and welcome")
> }
> }
>
> component FriendlyFareweller: Fareweller {
> func farewell() {
> print("I bid thee farewell")
> }
> }
>
> component InsultingGreeter: Greeter {
> func greet() {
> print("You make me sick")
> }
> }
>
> component InsultingFareweller: Fareweller {
> func farewell() {
> print("Get lost")
> }
> }
> ```
>
> And the `TrickingDoorman` might look like this:
>
> ```swift
> component TrickingDoorman: Doorman⎄(FriendlyGreeter, InsultingFareweller) {
> // optionally override any Doorman-defined functions
> }
>
>
> ```
>
> Here's how I think they would work:
>
> * Components must conform to at least one protocol.
> * Components must provide an implementation for all the things from the
> protocols - no part of it is 'abstract' - and they can't provide extra
> things (although it might be useful to allow some kind of config-values,
> but I'd say initially keep it simple).
> * Components can be composed of other components and override some/all of
> the borrowed behaviour. This should provide well defined
> multiple-inheritence semantics (not sure of details), some syntax would be
> required to allow the compiler to totally flatten the component, selecting
> which "parent" implementations to use if needed to satisfy all the
> protocols. Only the functions from the explicit protocols are pu

Re: [swift-evolution] [Pitch] Object aliases

2017-06-23 Thread Nevin Brackett-Rozinsky via swift-evolution
This sounds similar to lenses. Have you looked at previous lens discussions
on-list?

Nevin


On Fri, Jun 23, 2017 at 3:28 AM, Daryle Walker via swift-evolution <
swift-evolution@swift.org> wrote:

> I started a thread earlier this week about strong type-aliases and object
> aliases. Here’s a fuller proposal on object aliases.
>
> Feature name
>
>- Proposal: SE-
>- Authors: Daryle Walker , Author 2
>
>- Review Manager: TBD
>- Status: *Awaiting review*
>
> *During the review process, add the following fields as needed:*
>
>- Decision Notes: Rationale
>, Additional
>Commentary 
>- Bugs: SR- , SR-
>
>- Previous Revision: 1
>
> 
>- Previous Proposal: SE-
>
> Introduction
>
> This is a proposal to define aliases to objects.
>
> Swift-evolution thread: 1
> 
> Motivation
>
> Aliasing allows a named object to actually refer to another object instead
> of newly-allocated storage. Referring to an object with a simple name isn't
> very useful, but referring to an object needing a complex expression to
> point to it can help with reducing typing.
>
> However, aliasing has a cost. Compilers have to make certain assumptions
> if objects can have multiple names referring to them, and these assumptions
> reduce what kinds of optimizations can be made.
>
> Language design can make a difference in how code can be optimized.
> Languages like C and C++ assume aliasing is allowed by default, limiting
> how many optimizations can be done. More recent versions of C have a
> keyword ("restrict") to ban certain objects from aliasing. Other
> languages go the other way; you need to take extra measures to alias
> objects, since object handling bars aliasing by default.
>
> Swift is currently an alias-adverse language. The model for the equivalent
> of pointers is supposed to be for short-term use, and not persisted. Other
> constructs that would use references: read-write properties, read-write
> subscripts, and inout function parameters, can all be implemented by
> copy-in-then-copy-out, presumably to avoid alias dynamics and its
> anti-optimizations. So the scope of aliases here will be limited to
> local-scale renaming of object locations that the compiler can connect
> statically.
>
> Yes, the use case is currently weak, but it is a stepping stone for
> stronger cases, like changing the interface of an object with (currently
> not in the language) strong type-aliases without copies.
> Proposed solution
>
> The solution is to introduce a new kind of object declaration. It uses a
> new keyword pose in the same place as let or var. It must be initialized
> with an expression that specifies an object, and be typed with a
> layout-compatible type (like the unsafeBitCast function).
>
> struct Sample {
> var test1 = (1, 2, 3, "apple")
> //...
> func trial1() {
> pose firstTestNumber = test1.0
> print(firstTestNumber)  // prints "1"
> //...
> firstTestNumber = 4
> print(test1.0)  // prints "4"
> }
> }
>
> When an object is used, the compiler associates the object with some sort
> of location ID. An alias just reuses its original's ID instead of having
> one of its own.
>
> Here, the substitution is simple, but longer chains are imaginable. With a
> local-scope limitation, aliases work kind-of like macro constants in C.
> Detailed design
>
> Add to the "Grammar of a Declaration":
>
> *declaration* → *alias-declaration*
>
> Add a new section "Grammar of an Alias Declaration":
>
> *alias-declaration* → *attributes_opt* *declaration-modifiers_opt**pose*
> *pattern-initializer-list*
>
> An alias declaration can only be in the local scope of a function.
> Expressions that describe source objects must be:
>
>- a named object, including function parameters
>- a member of a qualifying tuple object
>- a stored property of a qualifying struct (or class?) object
>
> A source object must have a lifetime at least as long as any aliases to
> it. A source object cannot have willSet and/or didSetobservers. The alias
> poses as an object of its type annotation, defaulting to the source
> object's type if omitted. An annotation must be of the source object's type
> or a layout-compatible type. An alias has the same mutability status as its
> source object.
>
> An alias has the same operations as its annotated type, using the storage
> of the source object. An alias used as an inout function argument is
> banned if it and at least one other inout argument share memory (in whole
> or in part).
>
> Since source object

Re: [swift-evolution] [Core team] Addressing the SE-0110 usability regression in Swift 4

2017-06-19 Thread Nevin Brackett-Rozinsky via swift-evolution
Yay!
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-30 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, May 29, 2017 at 10:47 PM, Robert Bennett 
wrote:

> I think the goal of SE 0110 and to a lesser extent 0066 was to disallow
> this level of intelligence in the compiler.
>

Interesting.

I happen to think that the goal of SE–110

was to make Swift's type system “properly distinguish between functions
that take one tuple argument, and functions that take multiple arguments.”
Nowhere does that proposal discuss tuple destructuring, and nowhere does it
discuss optional parentheses around closure parameter lists.

I might go so far as to say that any commits which *do* affect those
things, cannot possibly be correct implementations of the accepted proposal
SE–110, because SE–110 did not describe any changes there.

With SE–66

the case is even more clearcut: that proposal explicitly addresses the
question, “Should we require parentheses in closure expression parameter
lists?“ and answers it in the negative. The core team’s notes

on accepting also specify, “The core team did not feel that this proposal
needed to include required parentheses within closures, which have their
own fairly specific grammar.”


While technically feasible, it's not desirable to overload parentheses in
> this manner.
>

I strongly disagree. Language features are desirable exactly to the extent
that they make life better for developers.

Moreover, parentheses are *already* optional in closure parameter lists.
Making them mandatory would be source-breaking for no benefit to
programmers. Plus having to write double-parentheses in “dict.map{ ((key,
value)) in … }” would be needlessly annoying.

In my view there have been far too many calls for making Swift “consistent”
in ways that actually make it less enjoyable to use. That is the opposite
of “Swifty”, and we should instead prioritize convenience for users above
rigid consistency of implementation.

In the case at hand, with Dictionary.map, the vast majority of the time the
user doesn’t actually care whether the closure takes two arguments or a
single 2-tuple argument. They just know that it takes a key and a value,
and they want to be able to write “dict.map{ (key, value) in … }”.

Sure, the closure *does* take a 2-tuple, and it does not take two
arguments, but the programmer *using* it shouldn’t have to bother about
that distinction most of the time. They just want to assign the key to one
identifier and the value to another. If they try to write “key, value”
without any parentheses the compiler will complain and they’ll add the
parens. But if the compiler demands a *second* set of parentheses, that
will just seem ridiculous.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-29 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, May 29, 2017 at 3:18 PM, Vladimir.S  wrote:

> On 29.05.2017 21:08, Nevin Brackett-Rozinsky wrote:
>>
>> barTuple{ (x, y) in }   // valid, destructuring one tuple
>> barTuple{ ((x, y)) in } // valid, destructuring one tuple with optional
>> parentheses
>>
>
> Here is the problem for me. According to SE-0066 closure declared as
> {(x,y) in} should be of type (Int,Int)->() and not ((Int,Int))->().
> Why do you want to be able to pass wrong function/closure type into
> barTuple?


 I don’t.

I want the compile to infer from context whether “{ (x, y) in }” is of type
“(_, _) -> _” with the optional parentheses included, or of type “((_, _))
-> _” with the optional parentheses elided. This is similar to how we use
context to determine whether “1” is of type Int or Double or something else
entirely.

If a closure appears in a context where it can only accept a tuple, such as
mapping a dictionary, then obviously its type should have a tuple
parameter. If a closure appears in a context where it can only accept two
arguments, then obviously its type should have two parameters.

I want the compiler to figure out, when possible from context, whether the
optional parentheses were included, so it “just works” for developers.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-29 Thread Nevin Brackett-Rozinsky via swift-evolution
Vladimir, using your function definitions I would like to have:

// Two parameters:
barParams{ t in }   // invalid, too few parameters
barParams{ (t) in } // invalid, too few parameters
barParams{ x, y in }// valid, two parameters
barParams{ (x, y) in }  // valid, two parameters with optional parentheses
barParams{ ((x, y)) in }// invalid, too few parameters

// One parameter which is a 2-tuple:
barTuple{ t in }// valid, one tuple parameter
barTuple{ (t) in }  // valid, one tuple parameter with optional
parentheses
barTuple{ x, y in } // invalid, too many parameters
barTuple{ (x, y) in }   // valid, destructuring one tuple
barTuple{ ((x, y)) in } // valid, destructuring one tuple with optional
parentheses

For completeness: if a closure takes *any number* of parameters, it should
be legal to list one identifier per parameter, separated by commas, with
optionally a pair of parentheses surrounding that list. Furthermore, if
*any* parameter is a tuple, it should be possible to replace the identifier
corresponding to that parameter with a pair of parentheses containing a
number of identifiers (separated by commas) equal to the arity of the
tuple. And this tuple-destructuring should work recursively, so if a tuple
contains a tuple [contains a tuple…] the inner tuples may optionally be
destructured as well.

To be clear: each tuple being destructured must have a pair of parentheses
containing the identifiers it is being destructured into. It is only the
very outermost parentheses around the entire parameter list of the closure
which should be optional.

Nevin



On Mon, May 29, 2017 at 1:32 PM, Vladimir.S  wrote:

> On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote:
>
>> On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution <
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>
>> We need to add back tuple destructuring in closure parameter lists
>> because this
>> is a serious usability regression.  If we're reluctant to just "do
>> the right
>> thing" to handle the ambiguity of (a,b), we should at least allow it
>> via
>> unambiguous syntax like ((a,b)).  I do think that we should just "do
>> the right
>> thing", however, with my biggest concern being whether there's any
>> reasonable way
>> to achieve that in 4.0.
>>
>> John.
>>
>>
>> I agree with John, the best thing for actually using Swift is to allow
>> tuple destructuring here, and the outermost parentheses (around the entire
>> parameter list of a closure) should continue to be optional. Requiring
>> double-parens would seem unnecessarily and arbitrarily…whatever the
>> opposite of “convenient” is.
>>
>> Nevin
>>
>
> If I understand correctly, correct me if I'm wrong, after *full*
> implementation of SE-0066, the function with two parameters should have
> different type than function with one tuple parameter:
>
> I.e.
> typealias FuncParams = (Int, Int)->()
> typealias FuncTuple = ((Int, Int))->()
>
> print(FuncParams.self) // should be (Int, Int)->()
> print(FuncTuple.self) // should be ((Int, Int))->()
>
> So, if we have
>
> func barParams(_ f: FuncParams) {
> f(1,2)
> }
>
> func barTuple(_ f: FuncTuple) {
> f((1,2))
> }
>
> and
>
> func fooWithParams(_ x: Int,  _ y: Int) {  }
> func fooWithTuple(_ tuple: (Int, Int)) {  }
>
> .. we should not be able to call
>
> barParams(fooWithTuple) // should be error: incompatible types
> barTuple(fooWithParams) // should be error: incompatible types
>
>
> If so, are you suggesting that this code should still be valid?
>
> barParams({tuple in}) // ?
> barTuple({x,y in}) // ?
>
>
> Will {x,y in} closure has ((Int, Int))->() type in this case?
> And if {tuple in} should be of type (Int,Int)->() ?
>
> If I'm not missing something, the only reasonable solution here is follow
> the SE-0066 rules for function types and allow special syntax ((x,y)) to
> deconstruct tuple parts in closure argument list, and such closure will
> have type ((Int,Int))->() as expected. So we'll have:
>
> barTuple({((x,y)) in ... })
>
>
>
>
>>
>> ___
>> 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] Revisiting SE-0110

2017-05-29 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

>
> We need to add back tuple destructuring in closure parameter lists because
> this is a serious usability regression.  If we're reluctant to just "do the
> right thing" to handle the ambiguity of (a,b), we should at least allow it
> via unambiguous syntax like ((a,b)).  I do think that we should just "do
> the right thing", however, with my biggest concern being whether there's
> any reasonable way to achieve that in 4.0.
>
> John.


I agree with John, the best thing for actually using Swift is to allow
tuple destructuring here, and the outermost parentheses (around the entire
parameter list of a closure) should continue to be optional. Requiring
double-parens would seem unnecessarily and arbitrarily…whatever the
opposite of “convenient” is.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Nevin Brackett-Rozinsky via swift-evolution
One possibility is to make parentheses consistently meaningful in closure
argument lists, so that “(a, b)” would exclusively mean “there is one
parameter of tuple-type, which is being destructured”, while “a, b” without
parentheses would exclusively mean “there are two parameters”.

That way you can destructure a tuple parameter if you wish (by using
parentheses) or you can leave the tuple intact (by listing a single
identifier without parentheses).

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


Re: [swift-evolution] [Review] SE-0163 [2]: String Revision: Collection Conformance, C Interop, Transcoding

2017-05-11 Thread Nevin Brackett-Rozinsky via swift-evolution
Looks good at first glance.

Is there a diff showing what’s changed though?

Nevin

On Thu, May 11, 2017 at 5:39 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> Hello Swift Community,
>
> The review of SE-0163: "String Revision: Collection Conformance, C
> Interop, Transcoding" begins now and runs through May 15th, 2017.
>
> The first version of this proposal was accepted with revisions. The
> proposed revisions were just a few additions that were publicly requested
> and agreed to during the first review, and this would not normally require
> a full second review. However, as we worked to implement the proposal,
> several minor naming changes suggested themselves that had not been
> previously discussed. The Core Team felt that the most conscientious
> approach would be to submit the whole proposal for a short re-review.
>
> The most noticeable change is that the Core Team feels StringProtocol
> would be a better name for the protocol unifying String and Substring.
> Unicode was felt to be slightly intimidating. Not using Unicode as the
> protocol name also has the benefit of allowing it to be used as a namespace
> to house Unicode-related types.
>
> The proposal is available here:
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0163-string-revision-1.md
>
> Reviews are an important part of the Swift evolution process. All reviews
> should be sent to the swift-evolution mailing list at:
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> or, if you would like to keep your feedback private, directly to the
> review manager.
>
> When replying, please try to keep the proposal link at the top of the
> message:
>
> Proposal link:
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0163-string-revision-1.md
> Reply text
>
> Other replies
>
> 
>
> What goes into a review?
>
> The goal of the review process is to improve the proposal under review
> through constructive criticism and, eventually, determine the direction of
> Swift. When writing your review, here are some questions you might want to
> answer in your review:
>
>- What is your evaluation of the proposal?
>- Is the problem being addressed significant enough to warrant a
>change to Swift?
>- Does this proposal fit well with the feel and direction of Swift?
>- If you have used other languages or libraries with a similar
>feature, how do you feel that this proposal compares to those?
>- How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>
> More information about the Swift evolution process is available at:
>
> https://github.com/apple/swift-evolution/blob/master/process.md
>
> Thanks,
> John McCall
> Review Manager
>
> ___
> 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] [Review] SE-0176: Enforce Exclusive Access to Memory

2017-05-08 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sun, May 7, 2017 at 2:04 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> Actually, `swapAt` does have a precondition that the elements differ.


Looking at the source code
,
the “swapAt” method is documented to have no effect when the indices are
equal:

/// Exchange the values at indices `i` and `j`.
///
/// Has no effect when `i` and `j` are equal.
mutating func swapAt(_ i: Index, _ j: Index)

Furthermore, the default implementation simply returns early when given the
same index twice:

extension MutableCollection {
  @_inlineable
  public mutating func swapAt(_ i: Index, _ j: Index) {
guard i != j else { return }
let tmp = self[i]
self[i] = self[j]
self[j] = tmp
  }
}

Contrast that with “swap” (found here
)
which is documented with “Precondition: `a` and `b` do not alias each
other.” And the implementation enforces that (at least in debug builds)
with:

_debugPrecondition(p1 != p2, "swapping a location with itself is not
supported")

So it looks like the precondition is only found on “swap”, and “swapAt”
should work properly (by doing nothing) when asked to exchange a single
index with itself.

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


Re: [swift-evolution] Pitch: Automatically deriving Equatable/Hashable for more value types

2017-05-05 Thread Nevin Brackett-Rozinsky via swift-evolution
On Fri, May 5, 2017 at 1:47 AM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> On Fri, May 5, 2017 at 12:41 AM, Brent Royal-Gordon <
> br...@architechies.com> wrote:
>
>> I would think only final classes could participate in this, since a
>> subclassable class would need to allow subclasses to override equality, and
>> you can't override a static `==` operator method.
>>
>
> I work so rarely with classes that I'm embarrassed to have to ask this
> question: can classes not satisfy Equatable with a `public class func ==`?
>

Currently:

class C: Equatable {
class func == (lhs: C, rhs: C) -> Bool {
return lhs === rhs
}
}

Yields an error, “Operator '==' declared in non-final class 'C' must be
'final'”.

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


Re: [swift-evolution] [Review] SE-0174: Change `filter` to return an associated type

2017-05-01 Thread Nevin Brackett-Rozinsky via swift-evolution
Another possibility is to make “map” generic on the return type, something
like:

extension Collection {
func map (transform: (Iterator.Element)
throws -> T.Iterator.Element) rethrows -> T {
var result = T()
for e in self { try result.append(transform(e)) }
return result
}
}

That way the user can choose what type they want. And since there is also a
more-specific implementation returning an Array, that is what you’ll get if
context does not constrain the type, so existing code will still work the
same.

We could do the same for “filter”, in which case the current proposal would
just change what the default type is. So…what I’m talking about here would
be purely additive and can happen later.

In any case, I do like the idea being proposed in SE–0174. If I have a
collection and I filter it down, it makes sense to still be the same kind
of collection. So, +1 from me.

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


Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

2017-04-18 Thread Nevin Brackett-Rozinsky via swift-evolution
>
>
>- What is your evaluation of the proposal?
>
> Strong +1, especially for the unary operators. They make code clear,
concise, and elegant.

Pattern matching against one-sided ranges looks great, and being able to
use postfix “...” to create a sequence is niche but nifty.


>
>- Is the problem being addressed significant enough to warrant a
>change to Swift?
>
> Definitely. The excessive verbosity of “startIndex” and “endIndex” is a
drag on readability when subscripting.


>- Does this proposal fit well with the feel and direction of Swift?
>
> Replacing a long awkward incantation with a simple and aesthetic
alternative is about as Swifty as it gets!


>
>- If you have used other languages or libraries with a similar
>feature, how do you feel that this proposal compares to those?
>
> Closest would be Matlab with colons for ranges and the “end” keyword. This
proposal is far superior.


>- How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>
> Participated the discussion when it came up on-list, and read through the
proposal again now that it’s up for review.

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


Re: [swift-evolution] [Accepted] SE-0169: Improve Interaction Between `private` Declarations and Extensions

2017-04-17 Thread Nevin Brackett-Rozinsky via swift-evolution
I am glad that “private” will become usable again in Swift 4. This
eliminates most of the pain caused by “fileprivate”.

However, I do not understand why this solution was chosen over renaming the
keywords. The discussion of alternatives here does not mention it, and the
only explanation given after SE-0159 is that renaming would cause “churn”.
Yet that renaming would be completely automatable by a migrator with no
change to semantics, whereas SE-0169 will require developers to manually
investigate each occurrence of “private” to see if the new meaning is still
appropriate, and introduce helper types to hide implementation details
where it is not.

Furthermore, I remain concerned that the mere act and fact of defining
“private” specifically to hide implementation details from other types in
the file will lead developers to put unrelated types together in a single
file, because that appears to be the intended purpose of the keyword.

At a meta-level, since mistakes like SE–0025 will be much more costly in
the source-stable future, we ought to consider adding a step to the Swift
Evolution process whereby accepted proposals are implemented in a beta
version of Swift, and a second review period can happen if new problems
become apparent in actual usage that were unforeseen during the initial
discussion. That way we are much more likely to catch emergent issues
before release.

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


Re: [swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

2017-04-17 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Apr 17, 2017 at 4:52 PM, Tino Heth <2...@gmx.de> wrote:

>
> the only way to hide one invariant from the other’s methods is to use
> helper types
>
> Could you elaborate here and give an example that uses such helper types?
>


Okay, let’s say we have a type Foo with a String property and an Int
property. The invariants we’ll preserve are that the String must begin with
“secret ” and the Int must be divisible by 3.

struct Foo {
private var secretString = SecretString()
private var divisibleBy3 = MultipleOfThree()

var x: Int {
get { return divisibleBy3.value }
set { divisibleBy3.update(newValue) }
}

var y: String {
get { return secretString.value }
set { secretString.update(newValue) }
}

// rest of the implementation
}

private struct MultipleOfThree {
private(set) var value: Int = 0
mutating func update(_ n: Int) { value = 3 * n }
}

private struct SecretString {
private(set) var value: String = "secret value"
mutating func update(_ s: String) { value = "secret " + s }
}

Now the only places that the invariants could possibly be broken are inside
the helper types themselves. Anything within the implementation of Foo can
call the “update” functions, but cannot directly alter the values inside
the helper types and so cannot violate the invariants. Thus, with this
pattern, to confirm that the invariants are preserved we need only look at
the helper types, which are short and self-contained.

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


Re: [swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

2017-04-17 Thread Nevin Brackett-Rozinsky via swift-evolution
All right, time to dive in!

First things first, the “helper visible” row in the table I posted is
actually unnecessary: a private helper type can have its visible members
unmarked (so, “internal”) and they will be available throughout the file.

Now, if we believe that cross-type sharing ought be avoided, then the
primary place “fileprivate” should occur today is when extending a type in
the same file. The one other time it might be unavoidable is when extending
an existing type to have an initializer that takes the new type. Thus in
“Foo.swift” we might have “extension Bar { init(foo: Foo) … }” and need to
see hidden details of Foo.

Similarly, if we think that unrelated types do not belong together in the
same file, then the bottom two rows (which deal with multi-type files) can
be expunged as well. After all if there are two types which must not have
privileged access to one another, they should go in separate files.

Thus the only place where “private” need appear today is when protecting
members of a type from the rest of that same type. However, as has been
mentioned on-list, “private” alone does not achieve sufficient
encapsulation for this purpose, because a private variable can be seen in
all functions located in the main type declaration.

Moreover, if a type has two separate invariants, and dedicated methods for
interacting with them, the only way to hide one invariant from the other’s
methods is to use helper types. It seems that “use a private helper type”
should be the preferred way to protect invariants, and if the helper type
needs to see the rest of the type’s members then it should be nested.

Putting everything together, an updated version of the table looks like
this, where the “Privileged init” row refers to the scenario described
earlier:


*No change*

*SE–0159*

*SE–0169*

*Rename*

*Simple file*

private

private

private

private

*Extensions*

fileprivate

private

private

private

*Privileged init*

fileprivate

private

fileprivate

private

*Helper hidden*

private

no hiding

private

scoped

*Invariants*

helper type

no hiding

helper type

helper type


*No change*

If we do not make a change, then we will be stuck using “fileprivate” in
perpetuity. This might be a purely aesthetic concern, but I would liken it
to a splinter in the finger. Yes it is small, but it hurts every time we
touch something with it, and it will keep hurting until we yank it out.

The existing meaning for “private” is really only useful to protect members
of a helper type. It should not be used for any other purpose because it
hamstrings the ability to add extensions, and it is insufficient for true
encapsulation outside of helper types.

*SE–0159*

If Swift takes the opinionated stance that one should not put things that
need to be hidden from each other in the same file, then SE–0159 is the
clear winner. After all, if you can’t hide things from other parts of the
file at all, then you won’t be tempted to try and thus you will keep your
separate types in separate files. This will also simplify the access
control model, making it easier to reason about code and decide which
visibility to use.

It will cause churn, however, as existing projects that use sub-file-level
hiding must adapt. In the future a submodule system with a visibility level
between “private” and “internal” (perhaps “protected”?) could re-enable the
use of helper types (in separate files!) to preserve invariants.

*SE–0169*

If we accept the current proposal, then we will only really need
“fileprivate” when extending another type to add something like an
initializer which requires privileged access to the main type in a file.
Additionally, people will be encouraged to use helper types for
encapsulating invariants, because the scope-based “private” of today will
no longer be a tempting-but-inferior alternative.

This option also causes churn, though perhaps in a good way as projects
which use “private” for encapsulation must switch to the superior design of
helper types. Furthermore, a private helper type can be nested in an
extension, so its implementation need not occupy space within the main type
declaration. It is worth noting than a private nested helper type cannot be
extended, and is thus guaranteed to be defined entirely within a single
code block, because it is only visible in the outer type and extensions
cannot be nested.

The access control model becomes more complex to explain, though perhaps
simpler to understand. However, one concern is that SE–0169 might
effectively encourage people to place unrelated types in the same file.
After all, one might reason, why would they have carved out this
weirdly-specific meaning for “private” if they didn’t expect and intend for
me to put several different types in a single file?

*Rename*

If we change the spelling of “private” to “scoped” and of “fileprivate” to
“private”, then there will be no extra work for developers because the
semantics are identical and migration can be aut

Re: [swift-evolution] [pitch] Comparison Reform

2017-04-16 Thread Nevin Brackett-Rozinsky via swift-evolution
Another option is to make a new type, not sure what to call it but I’ll use
“Num” for now, that is essentially the same as Double except it does not
represent NaN. After all, why should a numeric type ever be “not a number”,
and what sort of name is “Double” anyway except as a hold-over from legacy
standards?

Then people who really need IEEE semantics can keep using Double with all
its quirks. But everyone else who just wants a floating-point value can use
Num, and if they need to represent NaN they can use an Optional.
Operations which would produce NaN on Double will simply trap when done on
Num.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

2017-04-12 Thread Nevin Brackett-Rozinsky via swift-evolution
In order to evaluate this proposal, I created a table of as many relevant
scenarios as I could think of, and listed how each of the proposed
solutions would work there. The four access level systems I compared are:

*No change:* The existing Swift 3 *status quo* with “fileprivate” and
“private”.

*SE–0159:* Revert to the Swift 2 meaning of “private” (file visibility) and
eliminate scoped access altogether.

*SE–0169:* Expand “private” to include the current type and all its
extensions in the same file.

*Rename:* Change the spelling of “private” to “scoped”, and “fileprivate”
to “private”.

I ended up with a list of eight scenarios to evaluate. These are:

1. “Simple file”, a single type with no extensions.
2. “Extensions”, a single type and extensions thereof.
3. “Sharing”, multiple types that need privileged access to each other.
4. “Helper visible”, the interface of a helper (or nested) type for use
within the file.
5. “Helper hidden”, the details of a helper type that should not be visible
to other types.
6. “Invariants”, the details of a type that should only be touched by
dedicated methods.
7. “Multi-type”, multiple types that should not have privileged access to
each other.
8. “Multi-type + ext”, multiple types that should not have privileged
access to each other, and extensions thereof.

The entries in the table have seven possible values:

*private:* The “private” keyword works.

*fileprivate:* The “fileprivate” keyword works.

*scoped:* The “scoped” keyword works.

*private x2:* The “private” keyword works if the types are put into
separate files.

*fileprivate x2:* The “fileprivate” keyword works if the types are put into
separate files.

*helper type:* The goal can only be achieved by creating a helper type.

*no hiding:* The specified items cannot be hidden from the rest of the file.

Here is the completed and color-coded table (I hope it displays properly in
this email):



*No change*

*SE–0159*

*SE–0169*

*Rename*

*Simple file*

private

private

private

private

*Extensions*

fileprivate

private

private

private

*Sharing*

fileprivate

private

fileprivate

private

*Helper visible*

fileprivate

private

fileprivate

private

*Helper hidden*

private

no hiding

private

scoped

*Invariants*

private

no hiding

helper type

scoped

*Multi-type*

private

private x2

private

scoped

*Multi-type + ext*

fileprivate x2

private x2

private

private x2


*Analysis*

Some people have said on-list that they view cross-type sharing as an
anti-pattern. If that is true, then we can simply ignore the “Sharing” row
because it would not be worth optimizing for. This hardly changes the table
though, as that row is identical to the “Helper visible” row below it.

Regarding the “Invariants” row, note that a helper type can be used for
this purpose under “No change” and “Rename” just as well as under
“SE–0169”. The difference is that SE-0169 provides no other way to hide
invariants from the rest of the type, whereas the other two have an access
level suited to the purpose. Similarly, the multi-type rows can be
satisfied by separate files regardless of which access system is in place.

If a person takes the view that things in the same file should naturally
have access to one another, then the bottom four rows of the table can be
ignored. Such a person might have the mantra, “Only put things together if
they belong together”, and they would ask, “What else is in the file that
you are trying to hide from?”

For someone whose primary use-case is to put one type in a file and build
it up through extensions, the “Extension” row is of greatest concern. To
them, any of SE–0159, SE–0169, or renaming would let them use “private”
instead of “fileprivate” everywhere.

As a final remark, each of the four options has one notable benefit and one
notable drawback, not all of which are apparent from the above table:

*No change*
Benefit: No change to the language.
Drawback: Must use “fileprivate” to build up a type through extensions.

*SE–0159*
Benefit: Simplifies the access control model.
Drawback: Cannot protect invariants within a file.

*SE–0169*
Benefit: Cross-type sharing is clearly marked.
Drawback: Must use a helper type to protect invariants within a file.

*Rename*
Benefit: No change to semantics.
Drawback: Two separate keywords are changed.

 • • •

And now, having said all that, I need to go take a nap!

Once everything has percolated, I’ll come back to write a review of the
current proposal.

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


Re: [swift-evolution] [pitch] One-sided Ranges

2017-04-12 Thread Nevin Brackett-Rozinsky via swift-evolution
Strong +1, glad to see this happening!

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-06 Thread Nevin Brackett-Rozinsky via swift-evolution
On Thu, Apr 6, 2017 at 2:17 PM, Jordan Rose via swift-evolution <
swift-evolution@swift.org> wrote:

>
> We accepted SE-0025, though I wish we hadn't; we named the two levels
> "private" and "fileprivate", though I wish we hadn't; and now there is lots
> of existing code relying on that, and it would be mean and capricious to
> force people to change that code when they migrated to Swift 4. I don't
> like where we ended up but Swift does not exist in a vacuum.
>

I hardly think it is “mean” or “capricious” to provide a *fully automated
migrator* to make the keywords better.

The discussion of SE-0159 reached a near-consensus that the access levels
should be spelled “private” and “scoped”.

I was shocked and dismayed that the core team did anything other than
enthusiastically adopt that resolution.

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-05 Thread Nevin Brackett-Rozinsky via swift-evolution
On Wed, Apr 5, 2017 at 12:02 AM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:
>
>
>  - fileprivate should really become much more rare, which makes it more
> meaningful and significant where it occurs.  This was the original idea and
> intent behind SE-0025.
>

I would like to understand the reasoning here. I just looked back at
SE-0025 and I see this same assertion, but I cannot find the reasoning.
Could you explain it to me please?

Certainly I would love to make the *spelling* of “fileprivate” be entirely
nonexistent. But all the lines of logic I have come up with lead inexorably
to the conclusion that the *semantics* of “fileprivate” should be the
common, *de facto*, access level that people reach for when they need
encapsulation.

1. Someone makes a file with a single type in it, and marks the
implementation details “private”. At this point, it does not matter matter
which meaning “private” has, they all work the same so far.

2. The developer adds a free function to the file. Or an extension of
another type. Or another type entirely. And they put it in the same file
because it needs to work with the implementation details of the existing
type.

Now the difference between possible meanings of “private” matters. And if
it is anything short of “fileprivate”, then the developer has to go back
and change access levels. Things no longer “just work”.

The alternative scenario is that one adds something to the file which
doesn’t need privileged access to what’s already there. In which case the
questions are, “Why put it in the same file at all?” and “If there is a
good reason to put it in the same file, is there any *harm* in it being
able to see private members?”

Most developers most of the time should not have to think about
sub-file-level granularity. If things are in the same file it is because
they need to work together closely. We should be able to mark members
“private” and work with them across the file. This dramatically reduces the
cognitive burden, and the amount of time spent fiddling with access levels.

With any meaning of “private” less than “fileprivate”, developers end up
marking things “private”, then letting the IDE change it to “fileprivate”
when the compiler complains. This tells me that people actually want the
semantics of “fileprivate”, and they want it to be spelled “private”.

The main exception, where people truly desire and intend for
tighter-than-file encapsulation, is when certain invariants must be
preserved, and should not be touched except by dedicated methods. And
*that* is the important case worth making unambiguously explicit.

All the talk about calling out cross-type sharing within a file seems
superfluous. That is one of the principle reasons for putting multiple
types in one file to begin with. But preserving invariants, now *that*
deserves a meaningful and significant syntax, ideally something loud that
warns developers not to mess with it.

So, why exactly is there a desire to make the semantics of “fileprivate”
rare?

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-04 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Apr 4, 2017 at 10:00 PM, Brent Royal-Gordon 
wrote:

>
> There *may* be gains to be made by a ` `private` -> `scoped`/`fileprivate`
> -> `private` switch (I'm skeptical, but I can see the argument), but that's
> not in the offing, either.
>

For myself (and I suspect for many others) the file scope is exactly the
visibility level I want, at least until we get submodules. When I put
multiple types or extensions in the same file, it is precisely because I
want them to be able to work together at a low level. Even in a simple file
that just has one type and no extensions, I still want the file scope so
that in the future if I ever need to add other things to the file, it will
all just work without having to change access levels.

So under the current scheme, I end up writing “fileprivate” everywhere and
“private” nowhere. This gives the semantics I want, but it is absurdly
ugly. My only other option is to go full Pestov and make everything
“internal”, which is beautiful in its syntactic minimalism but doesn’t
achieve encapsulation.

SE-0025 took what I see as the basic, preferred, desirable access level and
made it for all appearances into a second-class citizen of the language.
Switching the spellings would fix that.

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-04 Thread Nevin Brackett-Rozinsky via swift-evolution
On Tue, Apr 4, 2017 at 3:30 PM, David Hart  wrote:

> I agree with you. But that soft-default requires a simple and recognisable
> name. That’s why I proposed SE-0159. But it got rejected. If we accept that
> fact, this proposal now attempts to give private back its original intent
> as a soft-default. It’s not the access model I would have preferred, but
> its better in my opinion than the current status-quo.
>

Right, the soft default should clearly be spelled “private”. And for all
the reasons that have been discussed at great length, it should mean
“visible in the current file”.



> The Core Team has said they will not consider renaming private. End of
> story. It’s not worth discussing something that has* *no* *chance of
> being accepted.
>

Last summer there were a few proposals that went through multiple rounds of
review. The core team took the community’s feedback in each round and
adjusted things, putting them back up for review several times before
settling on a final result.

I think that we as the Swift Evolution community should do the same thing
in reverse here. We should not accept the core team’s initial decision on
this particular issue because many of us are adamantly certain that they
are making another mistake, which will have a permanent detrimental impact
on the language. Instead we should insist that a revised version of SE-0159
which focuses specifically on changing the spellings be put up for another
round of review.

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-04 Thread Nevin Brackett-Rozinsky via swift-evolution
As I see it, this new proposal misses the mark in both directions. It does
not replace file-level visibility, because extensions of external types
wouldn’t be able to work with private declarations in the same file. And it
throws out a major use-case of scope-based access, which is to ensure that
invariants are only touched in specific places.

The vast majority of the time, if I am working in a file I want to be able
to access everything in that file. I think this is a phenomenal mental
model to have. It is extremely simple, it covers the most common use cases
perfectly, and it should be the soft default.

To the extent that we want to support protecting things within a file, it
is most beneficial to mark those declarations with a lengthy, unmistakeable
blazon. That way when you are reading code and come across something like
“fragilelocallyscoped var doNotBreakThisInvariant” you know that you must
be extra cautious about modifying it. In particular, such
invariant-sensitive items should not use the same keyword as other members,
because if they did there would be no warning sign for them.

Let me be abundantly clear: when someone is working in a file, they can
always change the access level of members if necessary. In order to protect
invariants, scoped visibility must very clearly inform readers that *this
item should not be touched* except via dedicated channels, and that its
visibility *should not be changed* as well. To convey that, those
declarations need to be distinct and unmistakable.

If you are reading through a file with many “private” declarations and one
or two “dangerproceedwithcaution” declarations, you are much more likely to
think twice before widening an access level in a potentially
invariant-breaking way than if they were all just “private”.

So, if we are going to keep scope-based visibility at all, it should
*definitely not* be spelled “private”. A longer, more-explicit keyword that
stands out prominently would be best, though nearly anything including
“scoped” would suffice as long as it is different from “private”.

We *must not* spell the invariant-protecting, danger-warning access level
“private”.

Leaving it as it is now would be *actively harmful*. Swift 4 is our last
realistic chance to get this right. We made a mistake in Swift 3. For our
own sake, and for the sake of the Swift language and its evolution process,
please let us fix this.

We can simultaneously solve the problem, retain scoped visibility, and
restore the file-level meaning of “private”, simply by changing the
spelling of two keywords. The core team’s reason for disfavoring that
approach, namely “churn”, is easily overcome, as they themselves noted, by
a fully automated migrator.

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


Re: [swift-evolution] Type-based ‘private’ access within a file

2017-04-03 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Apr 3, 2017 at 8:26 PM, Jarod Long via swift-evolution <
swift-evolution@swift.org> wrote:

> Pretty bummed out about the rejection. I know it's a petty aesthetic
> issue, but thinking about having to write "fileprivate" 5 or 10 years from
> now kills more of my enthusiasm about using the language than I'd like to
> admit. I think it's going to always be viewed by most as a major wart on an
> otherwise great language.
>

I agree. If someone made a fork of Swift whose only difference was to
change the spellings to “private” and “scoped”, and there was a way to use
it with Xcode, then I would use that instead of the official version in a
heartbeat. Heck, if someone made a preprocessor that just replaced the
access modifiers before compiling, I’d jump at the chance to use it.

My remaining hope is that Swift will acquire a submodule design which
renders “fileprivate” essentially redundant. If we get an access level that
means “visible in a group of tightly-related files” and it has a concise
spelling, then I will use that just about exclusively. If a file is not
explicitly part of a submodule then that new level would be synonymous with
“fileprivate”, and if it is in a submodule then that level is exactly what
I want anyway, so I can split up tightly-coupled implementations into
separate files.

I don’t know what the spelling for that access level would be, but if we
can find a good one then I’ll be happy to never have to type “fileprivate”
again.

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


Re: [swift-evolution] [Rejected] SE-0159: Fix Private Access Levels

2017-04-03 Thread Nevin Brackett-Rozinsky via swift-evolution
I am greatly disappointed by this decision. The existence of the keyword
“fileprivate” is an unfortunate blemish which never should have been
brought into existence. In my view, the churn caused by renaming “private”
last year was a major mistake, and we should correct it immediately.

I hope the core team will reconsider the spelling change to “private” and
“scoped”.

Nevin


On Mon, Apr 3, 2017 at 2:34 PM, Douglas Gregor via swift-evolution <
swift-evolution@swift.org> wrote:

> Proposal Link: https://github.com/apple/swift-evolution/blob/
> master/proposals/0159-fix-private-access-levels.md
>
> The review of ran from March 20...27, 2017. The proposal has been
> *rejected*.
>
> The core team had a lengthy discussion of this proposal as well as related
> ideas that came up during (and prior to) the review [*].
>
> SE-0159
> 
>  specifically
> sought to revert the main user-facing part of SE-0025
> ,
> which gave “private” lexical-scoping semantics and introduced
> “fileprivate”. The core team felt that there was sufficient evidence that
> more-restrictive-than-fileprivate access control is in use within the
> Swift community and in established patterns, such that it would be harmful
> to remove the functionality introduced by SE-0025
> 
>  at
> this point.
>
> The core team discussed the idea of renaming to keywords that was brought
> up in the thread as a way to address many of the concerns raised in
> SE-0159
> 
>  while
> providing the same language semantics. Specifically:
>
> * “private” -> “scoped”
> * “fileprivate” -> “private”
>
> The core team determined that such a change, while (technically) easy to
> automatically migrate, would introduce far too much churn in Swift code
> bases moving from Swift 3 to Swift 4, compromising the source stability
> goals set out for Swift 4.
>
> Finally, the core team discussed a different potential design for
> “private” that admits a limited form of type-based access control within
> files. We will open a separate discussion thread on Swift Evolution, with
> the subject "Type-based ‘private’ access within a file", and are seeking
> further discussion there and a motivated volunteer to turn it into a new
> proposal for Swift 4.
>
> - Doug Gregor
> Review Manager
>
> [*] Big thanks to Alex Martini for his excellent notes.
>
> ___
> 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] [Pitch] Add an all algorithm to Sequence

2017-04-02 Thread Nevin Brackett-Rozinsky via swift-evolution
I don’t think it is worth our collective effort to bikeshed this right now.
The feature might be nice, but it is a small thing that is easily done
without. Since we know that naming things is one of the two hard problems
in computer science , I
think it is better to hold off on adding this until we have time to figure
out the spelling.

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


Re: [swift-evolution] [Pitch] Add an all algorithm to Sequence

2017-04-01 Thread Nevin Brackett-Rozinsky via swift-evolution
If indeed “all(equal:)” is rarely needed, then perhaps it is best to leave
it out *and also* leave out the argument label from “all(matching:)”. Then
the signature would be similar to,

func all(_ predicate: (Element)->Bool) -> Bool

and the points-of-use would look like:

nums.all( isEven )
nums.all{ $0 == 9 }
nums.all{ n in n*n < 2 }

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


Re: [swift-evolution] [Pitch] Add an all algorithm to Sequence

2017-03-31 Thread Nevin Brackett-Rozinsky via swift-evolution
For “all(equal:)” I think there should be no argument label. We can already
write “nums.contains(9)”, so if we add “all” then we should be able to
write “nums.all(9)”.

Other than that, I like the idea.

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


Re: [swift-evolution] [Pitch] String revision proposal #1

2017-03-30 Thread Nevin Brackett-Rozinsky via swift-evolution
On Thu, Mar 30, 2017 at 3:39 PM, Robert Bennett via swift-evolution <
swift-evolution@swift.org> wrote:
>
>
> (for instance, mathematical sets may contain anything at all, including
> themselves)


Well actually they can’t ,
for…reasons  :-)

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


Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

2017-03-27 Thread Nevin Brackett-Rozinsky via swift-evolution
On Mon, Mar 27, 2017 at 1:47 PM, Charles Srstka via swift-evolution <
swift-evolution@swift.org> wrote:

> On Mar 27, 2017, at 12:00 PM, Ross O'Brien via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> 
>
>
> Creates a mechanism that actually makes sense for what people are using
> ‘extension’ for, solves the scoping problems, eliminates the need for
> fileprivate, solves all the problems that people are complaining about.
>

No it does not.

In addition to the protocol-conformance pattern that Ross describes, people
also use extensions to let types declared elsewhere (even in another
module!) work with types declared locally. So in Foo.swift we will have the
implementation of Foo, as well as things like “extension String { /*
Foo-related stuff */ }”.

The file-scope access level, which had been and should be spelled
“private”, enables those extensions of external types to access
implementation details of Foo to do their work. Thus Ross’s scheme does not
eliminate the need for file-level visibility at all. In my view, what we
really need is an access level *broader* than a single file, so that
implementation details can be made visible across a select group of
tightly-related files but not the rest of the module. However that is out
of scope for Swift 4.

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


Re: [swift-evolution] [Review] SE-0159: Fix Private Access Levels

2017-03-26 Thread Nevin Brackett-Rozinsky via swift-evolution
On Sun, Mar 26, 2017 at 12:57 PM, David Sweeris via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Mar 26, 2017, at 08:50, David James via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I propose instead that we revise to use Alternative #3, per Vladimir’s
> comment and revision.
>
> Revised version:
>
> *“3. Revert private to be file-based and introduce the scope-based access
> level under a new name (e.g.: scoped, local, etc), provided that the
> scope-based access modifier is not used at the top level of the file.” *
> (addendum via Vladimir’s revised comment)
>
>
> Yeah, within reason, I couldn't care less how "private"/"fileprivate" are
> *spelled*. What I'm against is removing the *functionality* of the
> current "private" without simultaneously providing a semantically
> equivalent replacement.
>


Conversely, I do not particularly care whether the functionality of
scope-based visibility stays or goes, but I find the spelling “fileprivate”
to be an ugly wart on an otherwise beautiful language.

Before the discussion on this review, I had a slight preference for
removing scope-based visibility in order to simplify the access control
model. After reading through the thread I have a slight preference for
keeping that functionality to enable compiler verification that invariants
are only touched via dedicated channels. I do not have a strong opinion
either way, and I would be fine to see scope-based visibility exist under
the name “scoped”, or be removed entirely.

However, the “fileprivate” keyword is one of the few things I actually
*dislike* about Swift. As in, when I am writing code I find it annoying and
offputting to use such a lengthy and inelegant term for one of the most
common access levels. I think it was a mistake to change the meaning of
“private” in SE-0025, and we should change it back posthaste.

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

2017-03-22 Thread Nevin Brackett-Rozinsky via swift-evolution
I strongly prefer that “private” should mean “visible in the current file”.

I am ambivalent between eliminating the scoped access level or renaming it
“scoped”, as long as “private” once more denotes file-level visibility.

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


Re: [swift-evolution] [Draft Proposal] Improve protocol inheritance behaviour

2017-03-14 Thread Nevin Brackett-Rozinsky via swift-evolution
The way I want things to work, “super” always calls the superclass’s method
with matching name and signature.

For the scenario you outlined, the superclass defines such a method, so it
gets called. For the situation relevant to this proposal, if the superclass
*obtains* such a method via default implementation of a protocol
requirement, I want exactly the same thing to happen.

Namely, when the subclass’s override calls “super”, I want the
superclass’s method with identical name and signature to be invoked. It
does not matter where the superclass *got* that method, all that matters is
the superclass *has* such a method, in which case it gets called.

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


Re: [swift-evolution] [Draft Proposal] Improve protocol inheritance behaviour

2017-03-13 Thread Nevin Brackett-Rozinsky via swift-evolution
Also, you don’t have to go through a superclass method to see the
problematic behavior. You can simply use a subclass instance in a variable
of superclass type:

let subclass: MyClass = MySubclass()
subclass.doTheSecondThing()
// Prints “The 'DEFAULT' 2nd method”

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


Re: [swift-evolution] [Draft Proposal] Improve protocol inheritance behaviour

2017-03-13 Thread Nevin Brackett-Rozinsky via swift-evolution
I agree there is a problem here, and the mental model I want is for the
language to act “as if” the default implementation of the protocol
requirement “had actually been” implemented by each type which uses it.

In particular, if a class uses a default implementation for one of its
protocol requirements, I want its subclasses to use the “override” keyword
when implementing that method. After all the parent class *does* have a
version of that method which can be called, it just happens to have
received that version by default.

So, for the example in your proposal, I would prefer that the subclass
write “override func doTheSecondThing()”.

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


Re: [swift-evolution] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Nevin Brackett-Rozinsky via swift-evolution
On Fri, Mar 10, 2017 at 4:16 AM, David Sweeris via swift-evolution <
swift-evolution@swift.org> wrote:

>
> I’m ok with doing it as an extension on `Comparable`, although we should
> add an overload for regular ranges, too.
>
> - Dave Sweeris
>

How would the semantics of that work?

Should “16.clamped(to: 0..<10)” produce 9 or 10?

What about “16.clamped(to: 0..<0)”, which is an empty range?

Does “16.0.clamped(to: 0..<10)” yield 10.0 or the next-smaller
representable Double?

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


Re: [swift-evolution] Add a `clamp` function to Algorithm.swift

2017-03-09 Thread Nevin Brackett-Rozinsky via swift-evolution
I’d be on board with an extension of Comparable so you could write
“16.clamped(to: 0...10)”. Something along the lines of:

extension Comparable {
func clamped(to range: ClosedRange) -> Self {
return max(range.lowerBound, min(self, range.upperBound))
}
}

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


Re: [swift-evolution] [Draft] Fix Private Access Levels

2017-03-06 Thread Nevin Brackett-Rozinsky via swift-evolution
I support this proposal to restore the file-based meaning of “private”.

Personally, I do not think we need any more fine-grained access level than
this, so I lean toward solution 1 (remove the scoped access level).
However, I would also be okay with solution 2 (rename the scoped access
level to scoped) if other people have a strong need for it.

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


[swift-evolution] [Draft] A Consistent Foundation For Access Control: Scope-Bounded Capabilities

2017-03-02 Thread Nevin Brackett-Rozinsky via swift-evolution
This is an intriguing proposal. There are parts I like, and parts that I
will have to think about more before drawing an opinion.

Personally, I would like to see public classes be inheritable, public
protocols be conformable, and public enums be switchable, unless specified
otherwise. However I will defer to those who have more experience writing
libraries.

On a first read-through, a few things stand out to me:

1. There are still five basic access levels: scope, private, internal,
public, and open. I think this is too many, and would prefer to just have
private, internal, and public.

2. The default is listed as “submodule”. I think the default should always
be “module”, and restriction to a submodule should be explicit.

3. There is still a file-specific access level. I think this should be
removed in favor of the submodule level. If submodules can be nested then
there is no loss of expressivity, because a file could be made its own
sub-submodule.

4. The proposal keeps a scope-based access level, which I think is
unnecessary.

All that said, there is a lot to like about this model, and I will let the
ideas percolate.

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


Re: [swift-evolution] [Accepted] SE-0104: Protocol-oriented integers

2017-03-02 Thread Nevin Brackett-Rozinsky via swift-evolution
One use-case that springs immediately to mind is creating ranges of
magnitudes. It is not sufficient to use abs() because that returns the same
type which may not be comparable.

Also, a fairly common operation on complex numbers (or indeed any
metric space) is to see if two values are within distance d of each other.
In other words, to check whether the magnitude of their difference is less
than d. This again requires comparability of magnitudes.

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


Re: [swift-evolution] [Accepted] SE-0104: Protocol-oriented integers

2017-03-02 Thread Nevin Brackett-Rozinsky via swift-evolution
Also not core team, but I didn’t realize this was missing during the
review. If I had I would have spoken up, because mathematically a magnitude
is *defined* as something that can be compared to see which underlying
object is bigger.

It is a measure of size, and it exists so that the sizes of objects can be
compared. Semantically, anything which is a magnitude must be comparable.

Putting that another way, if someone were to implement a type by giving it
a magnitude which wasn’t comparable, then that type should not be
considered numeric.

Even *vectors spaces*, where the objects aren’t even numeric because they
can’t be multiplied together, still have magnitudes which are comparable
since they must obey the triangle inequality.

I think the omission of ‘Comparable’ from ‘Magnitude’ should be considered
a bug in the proposal, and it should be amended as an obvious fix for an
oversight. Again, a magnitude is a measure of size, and it exists for the
purpose of being compared.

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


Re: [swift-evolution] A Comprehensive Rethink of Access Levels in Swift

2017-02-28 Thread Nevin Brackett-Rozinsky via swift-evolution
Rien, your example shows two things (well, three, but one relates to
variadic arguments not access levels).

First, it shows the importance of being able to prevent external overrides
of individual methods. I did not directly address that in my pitch, however
it could easily use the same syntax as closed classes, namely
‘final(public)’. I am not tied to that particular spelling, it just seemed
logical—better ideas are welcome.

Second, your example shows that even with today’s “soft default” of
closedness, developers still sometimes erroneously allow subclassing or
overriding. To put that another way, when a library author thinks something
should be ‘open’ in Swift 3, they mark it as such. The decision to make a
class or method closed is an intentional one, even today. Having it be a
“soft default” does not and cannot prevent the type of error it is alleged
to.

Also, unless there are subclasses in your library which override that
variadic convenience method, it should probably be marked ‘final’ and just
call through to the overrideable workhorse array-based version. No ‘closed’
required here. This provides further evidence that most of the time,
methods should either be overrideable or final, as ‘closed’ is a rare niche
case.

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


Re: [swift-evolution] [Draft] Refining identifier and operator symbology (take 2)

2017-02-27 Thread Nevin Brackett-Rozinsky via swift-evolution
I think the most important goal is to end up with the right set of operator
and identifier characters for *Swift*. The Unicode guidelines are a useful
tool for that purpose, and get us a long way toward where we want to be.
However at the end of the day we should weigh our success by how well we
have done for Swift, not by how rigidly we adhere to Unicode recommendations
.

Our treatment of emoji is a great example: the right thing for Swift is
different from the right thing for Unicode, so we choose to do what works
best for Swift. This proposal captures that very well.

Matching what Unicode does should be a means for us, not an end. A stepping
stone we can use when it helps. Unicode’s categorizations should inform and
guide out decisions, not constrain them.

With regard to the fact that reclassifying the infinity and empty set
symbols would be a breaking change, that is all the more reason to do it
now, for Swift 4, before it is too late. Those two characters have come up
in every iteration of this discussion on Swift Evolution that I can recall,
and I have not heard anyone argue that they ought to be operators. I think
it is safe to consider them low-hanging fruit.

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


Re: [swift-evolution] [Draft] Refining identifier and operator symbology (take 2)

2017-02-26 Thread Nevin Brackett-Rozinsky via swift-evolution
This looks very good Xiaodi, and I have a few thoughts about it.

First, is the intent that Swift will follow future changes to Unicode
operator recommendations, or that Swift will choose a “frozen in time” set
of Unicode recommendations to adopt? If the former, then we will likely see
source-breaking changes as Unicode evolves. And if the latter, then Swift’s
choices are apt to diverge even more from Unicode’s over time.

Second, it is well-established that programming operators do not have to be
mathematical. For example, Swift uses the punctuation marks ‘!’, ‘?’, and
‘&’ as operators in its standard library. The approach described in your
proposal does an excellent job at covering the core mathematical operator
characters in Unicode, however it does not appear to make such an effort
toward non-mathematical operators.

Of particular note, given that ‘?’, ‘¿’, and ‘‽’ are operator characters,
it seems inconsistent to omit ‘⸘’. Similarly, with ‘&’ an operator, one
would expect ‘⅋’ to be as well. I see that “expanding the set of operator
characters” is listed as a non-goal, however that does not make it an
anti-goal, and the proposal indeed expands the set by adding ‘\’. Likewise
“rectifying Unicode shortcomings” is listed as a non-goal, although the
proposal incorporates some 16 characters for Swift 3 compatibility.

Another point that may be worth considering, are the two specific
characters ‘∅’ and ‘∞’ which, although strongly mathematical, are
definitely not operators. They are names for things—objects, quantities—and
thus by the principle of least surprise they should be available for use in
identifier names. Just as one might write “let π = Double.pi” at the top of
a file, so too might one write “let ∞ = Double.infinity” or “let ∅ =
Set()” for use later on:

let y = sin(π * x)
if tan(θ) == ∞ { … }
var s = ∅

Thus, for the purpose of consistency, I think it makes sense to classify
‘∅’ and ‘∞’ as identifiers, as well as ‘⸘’ and ‘⅋’ as operators.
Alternatively, ‘∞’ could be a floating-point literal, in which case it
still would not be an operator.

I understand that you described this type of feedback (on particular
characters) as “less helpful”, however it appears that the “most helpful”
types of feedback are unnecessary: the proposal is well thought out, with a
strong core approach. It is only in the fine details that a few
improvements can be made, “lesser” though they may be.

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


Re: [swift-evolution] A Comprehensive Rethink of Access Levels in Swift

2017-02-24 Thread Nevin Brackett-Rozinsky via swift-evolution
Thanks for the feedback David,

The whole design and motivation behind SE-0117 is that it is not rare to
> want classes to be freely subclass-able internally while being closed to
> subclassing externally. Do you have arguments to contradict the lengthy
> points mentioned in the SE-0117 motivation section?


In fact I *agree* with the lengthy points mentioned in the SE-0117
motivation section!

That document does an excellent job laying out why it is important for
Swift to support closed classes, and I am wholly on board with that
rationale. It is a major reason I dedicated so much space to explaining
that we *should* continue to support closed classes. However, SE-0117 makes
no attempt to dispute the fact that closed classes are rarely needed. After
all, one can often use structs or final classes instead.

Only at the very end of its motivation section does SE-0117 contain a few
brief lines about “excess annotations”, and it is there I take a different
view. Since closed classes are quite infrequent, it is acceptable to place
a short annotation on the declaration in order to specify, “Yes, this
really is supposed to be a closed class.”

The loss is small because it just means writing ‘final(public)’ on an
uncommon sort of declaration, and the win is large because it dramatically
simplifies our access control system.


The reasons for the rarity above do not make much sense to me:
>
>- *"it must first of all be using classes rather than a protocol with
>conforming structs”: *we are discussing the merits of the different
>forms of subclassing prevention (public vs final), so I don’t see the
>reason for mentioning structs.
>
> Any library which models its features using structs, does not need classes
at all, so it certainly does not need a closed class hierarchy. This is
part of the reason why closed classes are rare in Swift.


We should not make “soft defaults” that tend to negatively impact the
>> clients of a library for the dubious benefit of enabling its author to
>> procrastinate on a basic design decision. If someone truly wants to publish
>> a library with a closed class, then we should support that. But it should
>> be an intentional decision, not a default.
>
>
> That’s a bit harsh. For me, it has nothing to do with procrastination, but
> with being *safe-by-default*, which is an important Swift goal. You are
> arguing for *useful-by-default*, which is only a different priority.


This is not an issue of safety. Classes are safe in Swift regardless of
their visibility or finality.

I am putting forward the idea that Swift, being an opinionated language,
should take the stance, “Classes can be subclassed, unless they are
‘final’.” Then if a library author wants to restrict subclassing, they can
use ‘final’ or ‘final(public)’ to do so.

This model allows progressive disclosure:

   1. Classes are subclassable
   2. ‘final’ prevents subclassing
   3. ‘final(public)’ prevents external subclassing


I’m a proponent for going back to a file-based private but your solution
> has two big disadvantages for me:
>
>- it makes impossible to have a file-based scope in submodules
>
> This is intentional. If you want certain files to share private details,
then put them in the same submodule. Otherwise, don’t.

The benefits are that it encourages people to keep submodules small and
focused, while supporting the pattern of building up types using
extensions, and without requiring lengthy files.


>- *private* would have different semantics depending if its in a
>submodule or not.
>
> I think my description may have been unclear. In my model there is only
one semantic meaning for ‘private’, and that is “visible in the submodule”.
Every file would naturally be its own submodule unless otherwise specified,
so the file-scope aspect is really just a consequence of having a submodule
with only one file in it.


>- it would make copy-pasting/moving files from a submodule to a
>top-module potentially breaking:
>
> Anytime code is moved out of a given visibility region, it will obviously
not be able to access things restricted to its previous location. This is
true of every access control system ever devised, and if I may be blunt it
is kind of the whole point.


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


[swift-evolution] A Comprehensive Rethink of Access Levels in Swift

2017-02-24 Thread Nevin Brackett-Rozinsky via swift-evolution
*Introduction*

There has been a deluge of discussion about access levels lately, all
attempting to simplify the situation. Shortly after Swift 3 was released,
many people realized that the new access modifier story was far more
complex than the old one, and expressed the belief that the changes may
have been a mistake.

In the months that followed, more and more people came to share the same
view, and stage 2 of Swift 4 has seen a profusion of proposals addressing
the issue. These proposals are generally small and focus on changing just
one aspect of access control. However, given the situation we are in now,
it is important to look at the problem in its entirety and arrive at a
cohesive solution.

*Background*

During the Swift 3 timeframe there were lengthy debates about access
control. The end results were to adopt SE-0025
,
which introduced the ‘fileprivate’ keyword and made ‘private’ scope-based,
and SE-0117
,
which made ‘public’ classes closed by default and introduced the ‘open’
keyword. At the time, there was broad agreement (and some dissent) that
these were the right changes to make.

That belief, as well as the numerous arguments which led to it, were
well-informed and thoughtfully considered. However, due to the inevitable
linear nature of time, they were not based on first-hand experience with
the new changes. Upon the release of Swift 3, we all gained that first-hand
experience, and it quickly became apparent to many people that the new
access control system was needlessly complicated, and not at all the
improvement it had been heralded as.

Rather than make it easy to encapsulate implementation details of related
types across multiple files, we had instead doubled down on requiring that
many things go in a single file or else reveal their secrets to the entire
module. Even worse, the new scope-based ‘private’ discouraged the preferred
style of using extensions to build up a type. To cap it off, we went from
needing to know two access modifier keywords (‘public’ and ‘private’) to
needing to know four of them (‘private’, ‘fileprivate’, ‘public’, and
‘open’) without even providing a way to share details across a small number
of related files.

*Motivation – Overview*

Many different ideas for access control have been expressed on the Swift
Evolution mailing list. Some people want ‘protected’ or ‘friend’ or
‘extensible’ or various other combinations of type-based visibility. Other
people (*cough* Slava) see no need for any levels finer than ‘internal’ at
all. The common points of agreement, though, are that ‘fileprivate’ is an
awkward spelling, and that the whole system is too complicated.

It is important that we as the Swift community are able to recognize our
mistakes, and even more important that we fix them. We originally thought
that the Swift 3 access control changes would be beneficial. However,
experience with them in practice has shown that not to be the case.
Instead, the language became more complex, and that has real costs. It is
time for a simplification.

The prevailing view from recent discussions is that there should be just
one access level more fine-grained than ‘internal’, and it should be
spelled ‘private’. Let us leave aside for the moment what its exact meaning
should be, and consider the other end of the scale.

*Motivation – Rethinking ‘public’*

Prior to Swift 3 we had just one access level more broad than ‘internal’,
and for simplicity of the model it would be desirable to achieve that
again. However, SE-0117 raised the point that certain library designs
require a class to have subclasses within the defining module, but not
outside. In other words, client code should not be able to create
subclasses, even though they exist in the library. Let us be clear: this is
a niche use-case, but it is important.

The most common situations are that a class either should not be
subclassable at all—in which case it is ‘final’—or that it should be
subclassable anywhere including client code. In order for a library to need
a publicly closed class, it must first of all be using classes rather than
a protocol with conforming structs, it must have a hierarchy with a parent
class that is exposed outside the module, it must have subclasses of that
parent class within the module, and it must also require that no external
subclasses can exist. Putting all those criteria together, we see that
closed classes are a rare thing to use. Nonetheless, they are valuable and
can enable certain compiler optimizations, so we should support them.

Currently, the spelling for a closed class is ‘public’. This makes it very
easy for library authors to create them. However, since they are a niche
feature and most of the time ‘final’ is a better choice, we do not need to
dedicate the entire ‘public’ keyword to t

  1   2   >