Re: [swift-evolution] [Pitch] Angle Type

2018-01-13 Thread BJ Homer via swift-evolution
An Angle type already exists in Foundation; see Measurement. You 
could add some convenience methods in an extension pretty easily.

import Foundation

typealias Angle = Measurement

extension Measurement where UnitType == UnitAngle {
var sine: Double {
let radians = self.converted(to: .radians).value
return sin(radians)
}

static var threeQuarterTurn: Angle {
return Angle(value: 0.75, unit: .revolutions)
}
}

let x = Angle.threeQuarterTurn
x.sine // -1

-BJ


> On Jan 13, 2018, at 9:31 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> I would like to see a full Geometry implementation but I don't think it 
> should be part of the standard library.
> 
> I've kicked around some ideas here: 
> 
> * https://gist.github.com/erica/8cb4b21cf0c429828fad1d8ad459b71b 
> 
> * https://gist.github.com/erica/ee06008202c9fed699bfa6254c42c721 
> 
> 
> and
> 
> * https://github.com/erica/SwiftGeometry 
> 
> 
>> On Jan 13, 2018, at 7:49 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>> Hi Evolution,
>> 
>> I would really like to see Swift gain an Angle type in the standard library. 
>>  Every time I have to deal with an angle in an api, I have to go figure out 
>> the conventions for that call.  Is it in degrees? Is it in radians?  What if 
>> it is in radians, but I want to think about it in degrees?
>> 
>> I ended up writing an Angle type for my own code a few years back, and I 
>> have to say it is really wonderful.  It has greatly simplified my graphics 
>> work.  It takes a lot of mental load off of my brain when dealing with 
>> Angles.
>> 
>> I can of course initialize it either as degrees or radians (or revolutions), 
>> but I can also just say things like ‘.threeQuarterTurn’, and then I can get 
>> the value back out in whatever format I like.  There are also useful 
>> additions that let me normalize the angle to different ranges and which let 
>> me snap to the nearest multiple of an angle. Both of these are enormously 
>> useful for user facing features.  I can also do math on angles in a way that 
>> makes geometric sense for angles.  It is also really useful for interacting 
>> with CGVectors in intelligent ways.
>> 
>> Using Doubles or CGFloats to represent angles everywhere is just 
>> semantically wrong IMHO, and it stops us from adding all of these 
>> angle-specific niceties.
>> 
>> Happy to provide code if there is interest…
>> 
>> Thanks,
>> Jon
>> ___
>> 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] [Pitch] Make try? + optional chain flattening work together

2018-01-12 Thread BJ Homer via swift-evolution
I agree that this behavior is annoying. However, wouldn’t it be source-breaking 
to change this now?

-BJ

> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution 
>  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().nonOptional()
> // 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] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

2018-01-03 Thread BJ Homer via swift-evolution


> On Jan 3, 2018, at 10:36 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> This does not help people who need to write a switch statement over an enum 
> vended by a module that ships with the OS keep their code up to date as the 
> module adds new cases. I find the example of `SKPaymentTransactionState` 
> provided by Brent Royal-Gordon here: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html
>  
> 
>  to be compelling.  There are rare but legitimate reasons to switch over all 
> known cases of a non-@frozen enum that ship with the OS.  These use cases 
> deserve proper language support.  I think Jordan’s solution strikes a good 
> balance.

I agree that the SKPaymentTransactionState example is compelling. However, I 
don’t understand what actual code a developer would put in the “unexpected 
case:” clause. That enum is related to handling in-app purchases; it’s expected 
that the app would react in some way to a transaction changing state. What 
should the app do if the transaction enters an “unexpected” state? Pop up an 
error to the user that the user can do nothing about? It’s great to get a 
compiler warning about a case like when the developer builds with the new SDK, 
but I don’t understand what the already-shipped app is supposed to do in a case 
like this.

For the SKPaymentTransactionState case, at least, it seems like the library 
needs to be responsible to only send known values to the client. Otherwise, the 
app can have no idea what to do.

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


Re: [swift-evolution] constant var

2017-12-12 Thread BJ Homer via swift-evolution
If I understand correctly, you want to be able to modify myDict from within 
MyClass, but not from outside it. In that case, you’re looking for private(set).

class MyClass {
  private(set) var myDict = [String : String]()
}

-BJ

> On Dec 12, 2017, at 12:34 AM, Inder Kumar Rathore . via swift-evolution 
>  wrote:
> 
> Hi All,
> Today I was writing code and faced a situation where I need to make a 
> instance variable a const i.e. it shouldn't accept new values from anywhere 
> but the problem is that I want it's content to be mutable.
> 
> e.g.
> 
> class MyClass {
>   var myDict = [String : String]()
> }
> 
> 
> I want above variable to be constant and if I make it like below
> 
> class MyClass {
>   let myDict = [String : String]()
> }
> 
> Then I cann't add key/value in the myDict like
> 
>self.myDict["name"] = "Rathore"
> 
> 
> I know swift and couldn't find anything related to this.
> 
> Can anybody help me?
> 
> 
> If there is no such method of doing it then I would suggest to either use a 
> syntax like
> 
> class MyClass {
>   const var myDict = [String : String]()
> }
> 
> I'm not using final here since that make a var not overridable.
> 
> 
> 
> -- 
> Best regards,
> Inder Kumar Rathore
> ___
> 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-07 Thread BJ Homer via swift-evolution


> On Dec 7, 2017, at 10:16 AM, Benjamin G  wrote:
> 
> 
> 
> On Thu, Dec 7, 2017 at 6:01 PM, BJ Homer  > wrote:
> Benjamin, 
> 
> It sounds like your concern is that people might write objects that just 
> store everything in a dictionary, instead of declaring typed properties. 
> Correct?
> 
>> On Dec 7, 2017, at 7:11 AM, Benjamin G via swift-evolution 
>> > wrote:
>> 
>> I think i answered that question many times as well (by masquerading 
>> dictionaries as regular classes), but if what i'm saying is simply 
>> impossible because of Swift type system even with the new proposal, i'd 
>> rather people tell it to me than ask the same question over and over..
>> 
>> ___
> 
> It would be possible, in theory, to write a class that used a dictionary as a 
> backing store for all its properties under this proposal. However, the 
> dictionary would have to be typed [String: Any?], and every property access 
> would be typed Any?. Your code would look like this:
> 
> class MyDynamicObject: DynamicMemberLookupProtocol {
> var storage: [String: Any?] = [:]
> 
> subscript(dynamicMember: String) -> Any? {
> get { return storage[dynamicMember] }
> set(newValue) { storage[dynamicMember] = newValue }
> }
> }
> 
> let x: MyDynamicObject = ...
> 
> // setting properties is easy!
> x.name  = “Benjamin”
> x.age = 3
> 
> // using them, though, is hard!
> var adults: [String] = []
> if x.age as! Int > 18 {
> adults.append(x.name  as! String)
> }
> 
> If you decide to create an object that stores everything in an ‘Any’, Swift 
> is going to force you to use an ‘as’ cast anytime you want to use it. That’s 
> super annoying.
> 
> So yes, it’s possible to create a type that masquerades a dictionary as a 
> regular class. But the ergonomics of doing so are sufficiently frustrating 
> that nobody is likely to do so. Swift makes it easy to declare typed 
> variables here, and the user experience for doing so is vastly improved (code 
> completion, compile-time checking, no more ‘as’ casting, etc).
> 
> So while it’s theoretically possible to do this, I don’t think it’s a concern 
> in practice. The incentives are already in place to encourage doing the 
> “right” thing in this case, even with the possibility of dynamic member 
> lookup.
> 
> -BJ
> 
> Hey, thanks for answering that part of the concern. i also came to this 
> point, but wondered if the dictionary couldn't be made of type [String: 
> DynamicValue] where DynamicValue would have some way to be  automatically 
> casted to string, int, etc, by reusing the same mechanism that the proposal 
> would use to convert PyVal to regular swift types. I stopped at this point.
> 


As far as I am aware, the proposal provides no mechanism for automatically 
converting back from PyVal to regular Swift types. You would have to do 
something explicit like myPythonValue.intValue, or String(myPythonValue).

-BJ

___
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-07 Thread BJ Homer via swift-evolution
Benjamin, 

It sounds like your concern is that people might write objects that just store 
everything in a dictionary, instead of declaring typed properties. Correct?

> On Dec 7, 2017, at 7:11 AM, Benjamin G via swift-evolution 
>  wrote:
> 
> I think i answered that question many times as well (by masquerading 
> dictionaries as regular classes), but if what i'm saying is simply impossible 
> because of Swift type system even with the new proposal, i'd rather people 
> tell it to me than ask the same question over and over..
> 
> ___

It would be possible, in theory, to write a class that used a dictionary as a 
backing store for all its properties under this proposal. However, the 
dictionary would have to be typed [String: Any?], and every property access 
would be typed Any?. Your code would look like this:

class MyDynamicObject: DynamicMemberLookupProtocol {
var storage: [String: Any?] = [:]

subscript(dynamicMember: String) -> Any? {
get { return storage[dynamicMember] }
set(newValue) { storage[dynamicMember] = newValue }
}
}

let x: MyDynamicObject = ...

// setting properties is easy!
x.name = “Benjamin”
x.age = 3

// using them, though, is hard!
var adults: [String] = []
if x.age as! Int > 18 {
adults.append(x.name as! String)
}

If you decide to create an object that stores everything in an ‘Any’, Swift is 
going to force you to use an ‘as’ cast anytime you want to use it. That’s super 
annoying.

So yes, it’s possible to create a type that masquerades a dictionary as a 
regular class. But the ergonomics of doing so are sufficiently frustrating that 
nobody is likely to do so. Swift makes it easy to declare typed variables here, 
and the user experience for doing so is vastly improved (code completion, 
compile-time checking, no more ‘as’ casting, etc).

So while it’s theoretically possible to do this, I don’t think it’s a concern 
in practice. The incentives are already in place to encourage doing the “right” 
thing in this case, even with the possibility of dynamic member lookup.

-BJ___
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-05 Thread BJ Homer via swift-evolution


> On Dec 5, 2017, at 12:13 PM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> let result = dynamic x.foo.bar  // will crash if foo or bar are not present
> 
> let result = dynamic? x.foo.bar // will return nil if foo or bar are not 
> present

Under the proposal given here, the compiler doesn’t know what will happen when 
“foo” or “bar” are not present. This proposal does not even require the 
implementation to report if a member is present or not, and there is certainly 
no guarantee of a crash in such a case. The only thing the compiler knows is 
that subscript(dynamicMember:) will be called.

Consider the following implementation:
 
struct PyVal: DynamicMemberLookupProtocol {

subscript(dynamicMember: String) -> PyVal? {
if let pythonMember = python_c_api.get(dynamicMember) {
return PyVal(pythonMember)
}
else {
return nil
}
}
}

let result = x.foo?.bar

There is no crashing here; result will be an optional type, and will be nil if 
the requested property does not exist. Some other use of 
DynamicMemberLookupProtocol might accept any value, and just log it to a file! 
In that case, neither crashing nor returning an optional is required.

-BJ___
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-05 Thread BJ Homer via swift-evolution


> On Dec 5, 2017, at 7:06 AM, Tino Heth via swift-evolution 
>  wrote:
> 
> Also, I don’t think anything can prevent all abuses (it’s an subjective 
> classification anyways) — people might just use PyVals because dynamic 
> behavior, and that would imho be a huge abuse.

Can you give an example of how someone would use such a PyVal to do something 
other than interoperate with Python? I’m having trouble imagining what your 
concern is. 

Specifically in the case of PyVal, I imagine it would already be hard-coded to 
call into Python for any dynamic lookup, so I don’t see how one could use “just 
use PyVal because dynamic behavior”. Are you saying that someone would just 
write all their code in a Python library, and then call into it from Swift?

-BJ

___
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-01 Thread BJ Homer via swift-evolution
Responses inline.

> On Dec 1, 2017, at 8:35 AM, Jon Gilbert via swift-evolution 
>  wrote:
> 
>> On Nov 30, 2017, at 08:10, Karl Wagner via swift-evolution 
>>  wrote:
>> 
>> Personally, I feel this system is designed to let you write Python, using 
>> Swift as a wrapper language - except unlike with Objective-C,
> 
> Let me paraphrase the proposal—it basically says this system is designed to 
> make it easier to “fake import” existing Python/Ruby/JS libs to make it 
> easier for people who depend on them to adopt Swift. Especially in the world 
> of server-side Swift, I can see how this could help speed Swift’s adoption.
> 
> However, I believe that you bring up an extremely valid concern. To 
> extrapolate from your points, this proposal seems to have a high potential to 
> erode what makes Swift special, and it provides a way to get around Swift’s 
> safe-guards, avoid writing Swift versions of libraries, and ultimately, avoid 
> hiring real Swift developers. 
> 

The point is not to let you write Python in Swift. If you want to write Python, 
just write Python. The point is to let you call Python libraries (or any 
dynamic language) from Swift, in the same way that we can already call C 
libraries from Swift. The ability to call C libraries does not make people 
“avoid hiring real Swift developers”; it just means that Swift developers can 
take advantage of C libraries. The goal of this proposal is to make Swift able 
to use more existing libraries. It sounds like your argument is “we want people 
to rewrite those libraries in Swift instead”. That’s a great goal, but it will 
only be achieved if Swift gains the kind of widespread cross-platform adoption 
that would be facilitated by this very proposal.


>> it doesn’t have any static information about what you can do or not. It 
>> can’t provide the “safe by default” guarantees are other core principles and 
>> set Swift apart from other languages.
> 
> Exactly. 
> 
> Look how JSON parsing is done in Swift 3.2 and 4.0—we make static types. The 
> 1’s and 0’s from a web response go through layers of proper error handling 
> before they become proper types Swift.
> 
> So why does this proposal keeps mentioning JSON parsing as an excuse for 
> making a dynamic ghetto within the language? Because some people are parsing 
> untyped JSON? Well, the solution for that is, type your frickin’ JSON. 

It doesn’t. There was one brief mention of a JSON example, to show how this 
proposal is useful for more than just Python interop. But most of the proposal 
talks about Python, not JSON.

> 
> Why compromise Swift’s static-ness and roll out the red carpet for the 
> dynamic, unwashed masses?
> 
> Wouldn’t it be better to create an AI that quickly translates Pyton, Ruby, or 
> JS into Swift? Augustus built huge public bathhouses for the unwashed Romans. 

If you can create an AI that quickly and accurately translates Python, Ruby, 
and JS into Swift, go right ahead. To the extent that those projects are not 
taking advantage of the dynamic features of their language, that’s likely 
feasible. It’s going to be a lot more difficult for the kind of code that does 
take advantage of the dynamic nature of the language. For example, dynamic 
languages can inspect the function name to vary its behavior. You can write one 
“fetchAllFromDatabase()” function, and then call it as 
fetchAllEntiresFromDatabase(), fetchAllUsersFromDatabase(), or 
fetchAllCommentsFromDatabase(), and automatically get the right behavior. I 
don’t think you’re going to be able to automatically create an AI that mimics 
that behavior on Swift; it fundamentally relies on the dynamic binding present 
in those languages.

It’s clear that you think dynamic languages are inferior to static languages. 
That’s fine, but the fact is that there are existing useful libraries in those 
languages which do not currently exist in Swift. Is it your argument that Swift 
should not be able to make use of such libraries because of their 
“unclean-ness”? I disagree.

> 
>> When we consider interoperability with other languages, it should be from 
>> the perspective of mapping their features to Swift’s philosophies.
> 
> Amen.
> 
>> This proposal takes the reverse approach, and makes Swift like Python, so 
>> I’m against it.
> 
> This is my concern as well. 
> 
> Perhaps there is a way to make the proposal require that you declare Swift 
> types and protocols that map to these other languages, with verbose error 
> handling for when this glue breaks down (just like we have for typed JSON). 
> 
> Then, we could also make scripts that auto-generate the necessary Swift 
> typing boilerplate interface code from the Python/Ruby/JS source, kinda like 
> we get for Obj.-C bridging headers. This could be a good step towards the 
> full AI translation that I mentioned.
> 
> Of course, maybe I am missing something here, and my opinion is wrong; Chris 
> will let us know if 

Re: [swift-evolution] Proposal: Introduce User-defined "Dynamic Member Lookup" Types

2017-11-27 Thread BJ Homer via swift-evolution
I like the proposal. Having a “magic” protocol isn’t ideal in some ways, but it 
seems like the best option for the moment, considering the other restrictions.

The name “DynamicMemberLookupProtocol” is a bit unwieldy, though. What about 
something like “SupportsDynamicMemberLookup“ or "SupportsDynamicMembers"? I 
know it doesn’t follow the usual protocol naming pattern, but for an empty 
“magic” protocol like this, it reads fairly well as a description of the 
capabilities of the type:

enum JSON: SupportsDynamicMemberLookup {
   // ...
}

Anyway, I like the proposal. The “Supports-“ prefix on the name may be a good 
idea, or may not. Either way, the “JSON” example in the proposal shows how this 
is useful for more than just bridging to dynamic languages, and is quite 
compelling to me.

-BJ


> On Nov 26, 2017, at 11:04 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> I’d like to formally propose the inclusion of user-defined dynamic member 
> lookup types.
> 
> Here is my latest draft of the proposal:
> https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438
> https://github.com/apple/swift-evolution/pull/768
> 
> An implementation of this design is available here:
> https://github.com/apple/swift/pull/13076
> 
> The implementation is straight-forward and (IMO) non-invasive in the compiler.
> 
> -Chris
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


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

2017-11-20 Thread BJ Homer via swift-evolution


> On Nov 20, 2017, at 10:09 AM, Drew Crawford via swift-evolution 
>  wrote:
> 
> The typical case for this function in my code is the identity closure, that is
> 
> let a: [Int?] = ...
> print(a.filterMap {$0})
> 
> filterMap is quite poor for this situation because *each* component in the 
> term is inaccurate:

filterMap is indeed an awkward name for this use case, just like flatMap is. In 
my experience, about half of my use cases use the identity closure, and half 
actually make use of the closure in a meaningful way. I would support a 
proposal to add something like Sequence.dropNils (actual name to be 
determined), and then we could let this proposal target the 
non-identity-closure use case.

-BJ

___
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-16 Thread BJ Homer via swift-evolution

> On Nov 15, 2017, at 11:07 PM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> 
>> Le 16 nov. 2017 à 06:29, Matt Gallagher via swift-evolution 
>> > a écrit :
>> 
>> My opinion is that filterMap is the right choice of name.
>> 
>> I'm completely biased, given that I already have a Swift library that uses 
>> filterMap, in exactly this context, for a Reactive Programming library:
>> 
>>  
>> https://github.com/mattgallagher/CwlSignal/blob/22f1d47895896d7b55bc59a4ee5394071f3c84cf/Sources/CwlSignal/CwlSignalReactive.swift#L453?ts=3
>>  
>> 
> 
> Another popular Reactive Programming Library uses filterMap with a different 
> signature, and a different meaning: 
> https://github.com/RxSwiftCommunity/RxSwiftExt/blob/3.0.0/Source/RxSwift/filterMap.swift#L32
>  
> 
> 
> There are already different interpretations on "filter" in "filterMap" in the 
> wild.
> 
> Gwendal Roué
> 

This library is using filterMap in exactly the same way proposed, except that 
they use a custom result type instead of Optional. So yes, it has a different 
signature, but I don’t think it has a different meaning. It’s still running a 
map operation that may filter some values out.

-BJ___
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-16 Thread BJ Homer via swift-evolution

> On Nov 16, 2017, at 2:52 AM, Gwendal Roué via swift-evolution 
>  wrote:
> 
>> The optional itself will stand for the boolean needed by the filtering 
>> operation.
> 
> What I meant here is that "filterMap" can only click in a developer's mind if 
> the the developer uses Optional as a Bool. When the closure returns nil, that 
> nil stands for false in the filtering operation. When the closure returns a 
> `some`, that some stands for true in the filtering operation.
> 
> Put in another way: to properly explain "filterMap" to someone who already 
> knows "filter", then you have to explain that optionals are used as booleans.

I disagree that you have to view Optionals as Booleans to understand filterMap 
as proposed. Optionals naturally represent the idea of either a value, or 
nothing. The filterMap operation runs a map that can filter stuff out. If you 
filter something out, you end up with “nothing”, which is exactly what 
returning nil means. So when I use filterMap, I map all the things I want to 
let through, and I filter the rest out by letting nothing through.

-BJ___
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-16 Thread BJ Homer via swift-evolution
mapSome is easy to misunderstand; the naïve reading suggests that only some of 
the source elements will be mapped, and doesn’t specify which ones. Even if the 
reader correctly intuits that it refers to Optional.some, they may incorrectly 
believe that it only maps the non-nil elements in the source sequence. I don’t 
think this is the right solution.

mapAndUnwrap is accurate to the behavior, but gives an ambiguous impression of 
what will happen to the nil values. I would worry that returning nil would 
cause a crash due to a force-unwrap. I don’t want the nil values unwrapped; I 
want them dropped from the result entirely, so calling it “unwrap” feels scary.

I really think we need something that mentions that the purpose of using this 
operation is to drop empty values.

-BJ

> On Nov 16, 2017, at 8:40 AM, Shawn Erickson via swift-evolution 
>  wrote:
> 
> I so far am most in favor of mapSome out of the names I have seen followed by 
> mapAndUnwrap (however the later is growing on me).
> 
> 
> To me the most important thing is when reading code that it is quick to 
> understand generally what is going on followed by discoverability of a new 
> comer. I think both of these are fairly clear on a quick read while a lot of 
> the others are heavily overloaded terms. I also they sufficiently 
> discoverable / learnable ... also mor so then some of the other overload 
> terms.
> 
> -Shawn
> 
> 
> On Wed, Nov 15, 2017 at 10:07 PM Gwendal Roué via swift-evolution 
> > wrote:
>> Le 16 nov. 2017 à 06:29, Matt Gallagher via swift-evolution 
>> > a écrit :
>> 
>> My opinion is that filterMap is the right choice of name.
>> 
>> I'm completely biased, given that I already have a Swift library that uses 
>> filterMap, in exactly this context, for a Reactive Programming library:
>> 
>>  
>> https://github.com/mattgallagher/CwlSignal/blob/22f1d47895896d7b55bc59a4ee5394071f3c84cf/Sources/CwlSignal/CwlSignalReactive.swift#L453?ts=3
>>  
>> 
> 
> 
> Another popular Reactive Programming Library uses filterMap with a different 
> signature, and a different meaning: 
> https://github.com/RxSwiftCommunity/RxSwiftExt/blob/3.0.0/Source/RxSwift/filterMap.swift#L32
>  
> 
> 
> There are already different interpretations on "filter" in "filterMap" in the 
> wild.
> 
> Gwendal Roué
> 
> ___
> 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] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread BJ Homer via swift-evolution

> On Nov 15, 2017, at 3:05 PM, Tino Heth via swift-evolution 
>  wrote:
> 
> Odd… exactly that is the reason why I think filterMap is the worst choice:
> 
> Both are established terms of art, but one has a meaning that doesn’t fit to 
> the operation.
> Applying filter can remove elements, but it can never change types (I feel 
> kind of silly to repeat this over and over, but so far, nobody took the time 
> to falsify this).

The concern about filter changing types is only relevant if you think of the 
filter applying to the result of the map, instead of being a part of the 
filterMap operation itself (an operation that is distinct from map).

Let’s imagine that we had this instead:

enum SelectiveMapResult {
case use(T)
case ignore
}

extension Sequence {
func selectiveMap(_ selectiveTransform: 
(Element)->SelectiveMapResult) -> [T]
}

let actualNumbers =
["1", "2", "apple", "banana", "5"].selectiveMap({ 
(x)->SelectiveMapResult in
if let value = Int(x) { return .use(value) }
else { return .ignore }
})

actualNumbers == [1, 2, 5]

The “selective” part of this operation doesn’t feel like it’s changing the type 
of the result, because SelectiveMapResult is easily understood to not be part 
of the mapping transformation; it just exists to tell us whether we should use 
the result of that particular transformation. Likewise, I don’t feel like the 
optional in filterMap is part of the mapping operation; it’s just serving the 
same role as SelectiveMapResult. (It should be obvious that SelectiveMapResult 
is just Optional with another name here.)

The name filterMap focuses on removing the ignored values, as does compactMap. 
The name selectiveMap focuses on retaining the non-ignored values. I’m not sure 
whether focusing on the positive or negative aspects is clearer here. I don’t 
particularly like the name compactMap, simply because I don’t have a lot of 
experience with languages that use “compact” to mean “drop the nil values”, and 
without that experience it doesn’t seem intuitive. I think filterMap is better. 
But if we introduced Sequence.compact() alongside .compactMap(), I’d probably 
get used to it.

-BJ


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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread BJ Homer via swift-evolution
I think we understand each other; we just disagree. If you believe that it 
makes intuitive sense to talk about “flattening” a sequence of optionals, then 
the current name perhaps makes sense. If you don’t think so, then the “flatten” 
name is awkward in this context. I don’t think most Swift users would find it 
intuitive, as Optional does not conform to Sequence, and there is no 
ValueContainer protocol on which we might define “flatMap”. (And introducing 
such a protocol is outside the scope of this proposal.)

Even if “flatMap” does make conceptual sense to you on a sequence of Optionals, 
though, the API as it exists right now still has the other problems mentioned 
in the proposal and throughout this thread:
Implicit promotion of non-Optional types to Optional types makes it easy to 
accidentally call the wrong function.
Discoverability: Users looking to filter out ‘nil’ values have to know about 
something that does not say “filter”. Most new Swift users do not naturally 
discover this functionality.
Fragility: Adding “Collection” conformance to a type caused source 
incompatibility (as shown in the original proposal). In general, adding 
conformances should not break existing code.
Fragility: Changing a type from Optional to non-Optional (or vice versa) should 
not silently change behavior. But in this case, because of implicit optional 
promotion, it can.
Non-obvious behavior: In my experience, new Swift users do not intuitively 
understand what it means to “flatMap” a sequence of optionals, and could not 
intuitively understand the meaning of “flatten” in this context.
We can make Swift a more intuitive language by not pretending that Optionals 
are Sequences when they’re really not, and we can make it a more robust 
language by avoiding ambiguity between different versions of Sequence.flatMap 
in the presences of subtle type changes.

Anyway, I guess the review period ended last night, so we’ll know soon how this 
turns out.

-BJ


> On Nov 15, 2017, at 8:39 AM, Tino Heth <2...@gmx.de> wrote:
> 
> Looks like I finally have to draw on drawings... (hope the pictures aren’t 
> considered inappropriate content ;-)
> 
> But after all, it might be the best way to convey my point anyways: I’m not 
> thinking in terms of type names (why should it only be possible to flatten a 
> „Sequence“? Many people associate this operation with lists, which aren’t 
> common in Swift at all) or implementation details (neither Optional nor 
> Sequence actually has a flatten-method).
> Instead, I tend to look at the easiest way to explain how to get from input 
> to output, so here is what I have in my mind when I speak about 
> Sequence-Sequence flatmap:
> 
> 
> https://imgur.com/hy4rel1 
> 
> There is a transform, which turns an input value (red circle) into a 
> collection (blue basket) of output values (green squares).
> map takes an array of those input values, and stores each result-collection 
> in an array (light blue).
> flatten takes that container, unwraps each sub-collection, and stores its 
> contents together with the other elements.
> Note that empty collections aren’t skipped or removed — they just have 
> nothing that they could contribute to the final result, so no trace of them 
> is left.
> flatMap just is flatten performed on the output of map.
> 
> Now, Optionals… I could simply say „think of those as an array with a maximal 
> size of one“ — but because there’s really no fundamental difference, I just 
> copied the sequence-illustration, and changed one tiny bit: The 
> transformation doesn’t return multiple items now, so that the blue basket can 
> act as representation for an Optional.
> 
> 
> 
> https://imgur.com/qq95b31 
> 
> So conceptionally, both overrides are equivalent: The transformation always 
> produces something — an Optional, and that can contain a value, or it can be 
> empty, just like an array.
> You also see that the flatten step really does what it says: It removes one 
> layer of objects, and leaves a flush surface without gaps.
> 
> So, that should really be my last word in this discussion — I won’t add an 
> animation or start singing about Optionals ;-)
> 
> - Tino
> 

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-14 Thread BJ Homer via swift-evolution
“Flatten”, in the context here (flattening a Sequence of Optionals), only makes 
sense if you consider Optional as a sequence of zero or one elements. While 
such a sequence does act very similarly to an Optional, the fact remains that 
Optional is not a Sequence, and is generally not treated as one by any other 
part of the language. It fundamentally makes no more sense to “flatten" a 
Sequence of Optionals than it does to “flatten" an Optional of a Sequence.

In my mind, filter makes sense because I’m filtering out some of the results of 
the transformation operation before they get put into the resulting array. It’s 
a different kind of operation; not a map, but a filterMap. (Maybe filteringMap 
would be clearer?) The operation is not “map into a new array, then filter”. 
It’s “run this transformation for each item. If it produces something, keep 
it.” There’s no filter or compact that runs on the entire collection.

-BJ





> On Nov 14, 2017, at 7:50 AM, Tino Heth via swift-evolution 
>  wrote:
> 
> 
>> Yeah but it seems clear from the return type so I am not sure that much 
>> confusion would really exist.
> 
> 
> Afaics, there already is lots of confusion — that’s the reason for me to 
> write a sequence of posts in this topic, instead of an Optional ;-)
> The word „flatten“ is a quite honest description, so I wonder why words like 
> filter, remove, ignoring or skipping should be used instead.
> 
> „Compact“ would be less irritating, but I could imagine that it indicates 
> something like eliminating repeated occurrences.
> 
> Tino
> 
> (I’m quite close to attach a hand-drawn illustration of the flatMap process — 
> I don’t think you want that to happen ;-)
> 
> ___
> 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-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread BJ Homer via swift-evolution


> On Nov 11, 2017, at 9:49 AM, Michel Fortin via swift-evolution 
>  wrote:
> 
> I think it fits well for arrays. Not sure about optionals.

This proposal only suggests changing the one on sequences, and even then, not 
all of them. Currently, the following exist:

// Reminder: Int("someString") returns 'Int?' in the following examples

// (1) Sequence.flatMap() with a closure returning an optional, dropping 
anything that maps to nil
["1", "mountain", "2"].flatMap({ Int($0) })  // [1, 2]

// (2) Sequence.flatMap() with a closure returning a sequence, then joining 
(“flattening”) them into one array
[1, 2, 3].flatMap({ Array(1...$0) }) // [1, 1, 2, 1, 2, 3]

// (3) Optional.flatMap() with a closure returning an optional, flattening a 
nested optional.
("3" as String?).flatMap({ Int($0) }) // Optional(3)


The 2nd and 3rd variants are both about flattening nested structures, and would 
not change under this proposal. We would keep calling them “flatMap()”. There 
is no a proposal to add Optional.filterMap, nor to change the Sequence.flatMap 
variant that flattens nested sequences. The only change proposed it is to 
rename the first one.

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-10 Thread BJ Homer via swift-evolution


> On Nov 10, 2017, at 5:07 AM, Tino Heth <2...@gmx.de> wrote:
> 
> A: Well, it does a mapping, and then applies a filter to get rid of nils,

I prefer to think of it this way: it does a mapping, and keeps the results 
where the closure did not return nil. In the example given earlier, the closure 
returned Optional.some(nil), which is not “nil”.

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-09 Thread BJ Homer via swift-evolution
On Nov 9, 2017, at 11:36 AM, Kevin Ballard via swift-evolution 
 wrote:
> 
> On Wed, Nov 8, 2017, at 09:29 PM, Paul Cantrell via swift-evolution wrote:
>> The problem in the Doodads example is that the name flatMap is used to 
>> identify two distinct intents: concatenating arrays and filtering nils. One 
>> can argue that those two operations are, in some lofty abstract sense, if 
>> you squint, two instances of some more general pattern — but I don’t think 
>> it’s fair to say that they represent the same intent. These separate intents 
>> deserve separate names.
> 
> They absolutely represent the same intent if you think of an optional as a 
> collection of zero or one elements.
> 
> -Kevin Ballard

But as `Optional` does not conform to collection, I would suggest that the vast 
majority of of developers do _not_ think of them as a collection of zero or one 
elements. (I certainly don’t know any who naturally think of it that way.) We 
don’t treat Optional as a collection anywhere else in the API, and it seems odd 
to do so in just this one case.

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


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

2017-11-09 Thread BJ Homer via swift-evolution
> 
> On Nov 9, 2017, at 11:35 AM, Tino Heth <2...@gmx.de> wrote:
> 
> 
>> This proposal only proposes renaming the “filterNonesAndMap” variant (though 
>> that name is misleading, it would be “filterNonesAfterMapping” if anything); 
>> the other uses of flatMap will remain unchanged.
> … then it should be really right: As I learned in the thread, there is a map 
> step before filter, and another map afterwards - so 
> „filterNonesAfterMappingAndMap“ (that’s why I don’t like the use of the term 
> „filter“ here — if you want an accurate name that contains this verb, it gets 
> quite complicated…)
 
But obviously “filterNonesAfterMappingAndMap” is not a name we’re going to end 
up with. You can argue that “filterMap” is not completely faithful to the 
internal implementation, but I think it’s clearly better than “flatMap” in this 
case, which is even more incorrect. I’m not opposed to finding a better name 
than “filterMap”, but so far I haven’t seen one.

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


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

2017-11-09 Thread BJ Homer via swift-evolution


> On Nov 9, 2017, at 9:37 AM, Sam Warner via swift-evolution 
>  wrote:
> 
> I accept the motivation for this change, although I would mention that:
> - in 2.5 years on a ~200k lines of Swift project
> - we've seen a plenty of instances of `flatMap` used where `map` would have 
> been sufficient, but
> - we've never burned time on tracking down the sort of compiler issue 
> described by the author in the Motivation. As I say, the argument is fair, 
> but I am questioning how frequently this problem occurs.
> 
> I can't speak to the previous attempts to solve this problem, but I'd add my 
> voice to anyone advocating solving this by having a compiler warning when 
> `flatMap` is used redundantly(?).
> 
> If this proposal were to be accepted, I'd also question the choice of 
> `filterMap` as a name. This name is presumably shorthand for 
> `filterNonesAndMap`, which conveniently ignores the following:
> - `flatMap` may be used on a sequence-of-sequences to flatten our to a 
> single-dimensional sequence.
> - `flatMap` may be used on other 'box' types, e.g. on an optional: 
> `Optional("foo").flatMap { .some($0 + "bar") }` or on the common 
> `Result` type.
> 
> Any re-naming of one `flatMap` should take these other uses into account, as 
> they share conceptual details.
> 
> Thanks,
> 
> Sam

This proposal only proposes renaming the “filterNonesAndMap” variant (though 
that name is misleading, it would be “filterNonesAfterMapping” if anything); 
the other uses of flatMap will remain unchanged.

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-09 Thread BJ Homer via swift-evolution
On Nov 9, 2017, at 9:13 AM, Tino Heth via swift-evolution 
 wrote:
> 
> 
>> Experienced programmers (as experienced as any Swift programmer can be for a 
>> 4-year-old language) frequently use flatMap when they mean map
> When you look at those examples:
> What would stop those programmers to use filterMap in the exact same way, 
> instead of switching to map?
> A hypothetic migrator most likely would just replace names…


The migrator would already have to be aware of the return type of the closure 
(to avoid migrating cases where it’s actually returning a sequence as 
expected), so the migrator could easily only migrate the ones that are actually 
returning optionals in the first place.

Programmers could continue to use filterMap incorrectly, but it would be a more 
explicit choice. Currently, there’s a sense among some Swift users (including 
some that I know personally) that flatMap is the “smart” thing to use with 
collections because monads or something, without any real understanding of why 
that is. (Remember, Swift doesn’t even have a “flatten()” function anymore, so 
the name “flatMap" is far from obvious.) I think it’s less likely that people 
will continue to use “filterMap” when they know no filtering is happening.

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-07 Thread BJ Homer via swift-evolution
• What is your evaluation of the proposal?
I approve. This variant of ‘Sequence.flatMap’ is confusing to newcomers, and is 
inconsistent with the standard term-of-art usage of “flatMap”. People can learn 
what it means, but it continues to feel awkward. There will be some code churn, 
but it’s easily automatable and improves the clarity of the code. If we leave 
the existing spelling in place as deprecated, then we even preserve source 
compatibility.

• Is the problem being addressed significant enough to warrant a change to 
Swift?
I think so. The existing spelling of this functionality has three problems:
Discoverability: Users looking to filter out ‘nil’ values have to know to look 
for something that doesn’t say “filter”
Unexpected behavior: Users who are unfamiliar with the concept of Optionals as 
a Sequence-of-one have difficulty understanding why this is called “flatMap”. 
They don’t know what it does. I’ve seen this many times.
Brittleness: The functionality changes dramatically if the body of the function 
changes from returning an Optional to a Sequence. An example of this was given 
in the proposal, but here’s another one: 
struct Thing {
var name: String? // What if this becomes non-optional in the future?
}

// If Thing.name is optional, this returns an array of names (with nil filtered 
out)
// If Thing.name becomes non-optional, this now returns an array of all the 
characters in all the names, concatenated
things.flatMap { $0.name }

In general, changing from optional to non-optional causes compiler warnings in 
cases where something wasn’t expecting that. This isn’t likely a common 
problem, but it isn’t a great argument in defense of the current situation.


• Does this proposal fit well with the feel and direction of Swift?
Yes. Clear names are a common theme in Swift, and we have other proposals in 
Swift 5 with a similar goal.

• If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?
It makes us behavior more like those other languages, reducing user surprise.

• How much effort did you put into your review? A glance, a quick reading, or 
an in-depth study?
I was in the process of writing up a similar proposal myself when this one came 
out. I’ve thought about this quite a bit, and I think it’s the right choice.


-BJ


> On Nov 7, 2017, at 4:23 PM, John McCall via swift-evolution 
>  wrote:
> 
> Hello, Swift community!
> 
> The review of "SE-0187: Introduce Sequence.filterMap(_:)" begins now and runs 
> through November 14th, 2017.  The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.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 me as 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/0187-introduce-filtermap.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 
> 
> 
> As always, thank you for contributing to the evolution of Swift.
> 
> 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] continuations - "extensions on steroids" idea

2017-11-01 Thread BJ Homer via swift-evolution
Again, though, “anyone” here only means “anyone working in the same module”. 
Which is a very restricted set of “anyone”: it only includes people who already 
have full access, and could just modify the original struct anyway.

-BJ

> On Nov 1, 2017, at 9:28 AM, Mike Kluev via swift-evolution 
>  wrote:
> 
> 
> On 1 November 2017 at 15:22, Adam Kemp  > wrote:
> I don’t see why “parts” would need to be named. That seems overly complex for 
> little benefit. 
> 
> 
> name and ledger are essential in this proposal.
> 
> no name -> 
> no ledger (how to reference it?) -> 
> anyone can write parts of your class -> 
> anyone can add variables to your class ?! -> 
> anyone can access private members of your class ?! 
> 
> makes no sense without a name and a ledger.
> 
> Mike
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [draft] Target environment platform condition

2017-10-26 Thread BJ Homer via swift-evolution
Example: the iOS Keychain APIs do not support access groups on the simulator, 
so if you try to make a keychain query that targets an access group, you get no 
results. This means that in order for my app to operate correctly on simulator, 
I need to pass different parameters on simulator and device. This is an 
unfortunate distinction that ideally should not exist in a simulator, but 
unfortunately such cases do exist.

(This was at least true in iOS 9, and I haven’t seen any indication that it has 
changed.)

-BJ

> On Oct 26, 2017, at 5:43 AM, Karl Wagner via swift-evolution 
>  wrote:
> 
> I’m currently -1 on this, because I don’t think simulator/device is a 
> worthwhile-enough distinction for a built-in condition.
> 
> - Are you maybe looking for a Debug/Release condition? Because we already 
> have that, through compile-time variables (the “-D” option).
> - Does your platform’s simulator/emulator expose any additional API? Great! 
> Take a look at #canImport…
> - Why else would you need to distinguish simulator/device, and why are OS and 
> architecture not sufficient for that case?
> 
> Karl
> 
>> On 25. Oct 2017, at 05:05, Graydon Hoare via swift-evolution 
>>  wrote:
>> 
>> Hi,
>> 
>> I'd like to propose a variant of a very minor, additive proposal Erica Sadun 
>> posted last year, that cleans up a slightly messy idiomatic use of 
>> conditional compilation in libraries. The effects should be quite limited; 
>> I'd call it a "standard library" addition except that the repertoire of 
>> compiler-control statements isn't strictly part of the stdlib.
>> 
>> Proposal is here: 
>> https://gist.github.com/graydon/809af2c726cb1a27af64435e47ef4e5d
>> 
>> Implementation (minus fixits) is here: 
>> https://github.com/graydon/swift/commit/16493703ea297a1992ccd0fc4d2bcac7d078c982
>> 
>> Feedback appreciated,
>> 
>> -Graydon
>> 
>> ___
>> 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] Pitch: Deprecate/remove AnyObject method dispatch

2017-10-25 Thread BJ Homer via swift-evolution
That would be a Cocoa-side change, since UIView, NSView, NSMenuItem, NSCell are 
all Cocoa-level objects. (I’m not aware of any other type that would be 
commonly passed as a ‘sender’ parameter and would have a tag.) That change 
wouldn’t go through Swift-Evolution.

So in theory, if Swift 5 decides to get rid of the AnyObject dispatch, the 
Cocoa teams at Apple could work around that by introducing “@objc protocol 
IntegerTagged”, and introducing a migrator pass to look for '(sender as 
AnyObject).tag’ and rewrite it as `(sender as! IntegerTagged)?.tag.

If the ‘tag’ property is the only reason to keep AnyObject dispatch, I don’t 
think it’s worth its weight in the language.

-BJ

> On Oct 25, 2017, at 8:28 AM, Charles Srstka via swift-evolution 
>  wrote:
> 
> I guess, but doesn’t it seem far more elegant to have a protocol for 
> tag-containing objects? This is a feature that’s pretty heavily used…
> 
> Charles
> 
>> On Oct 24, 2017, at 6:06 PM, Slava Pestov > > wrote:
>> 
>> You can implement an @objc protocol with an optional requirement, and make 
>> NSObject conform to it.
>> 
>> Slava
>> 
>>> On Oct 24, 2017, at 4:05 PM, Charles Srstka >> > wrote:
>>> 
 On Oct 24, 2017, at 5:02 PM, Slava Pestov via swift-evolution 
 > wrote:
 
 Thoughts? Does anyone actually rely on this feature, instead of just 
 stumbling on it by accident once in a while?
>>> 
>>> The main thing I can think of off the top of my head is getting the tag 
>>> from the sender in an IBAction:
>>> 
>>> @IBAction private func someAction(_ sender: Any?) {
>>> guard let tag = (sender as AnyObject?)?.tag as Int? else { return }
>>> 
>>> ...
>>> }
>>> 
>>> Unfortunately given how many unrelated Cocoa objects there are that 
>>> implement -tag, it’s not really practical to implement this without the 
>>> AnyObject dispatch. If a TagContaining protocol could be introduced and all 
>>> the objects that implement -tag could be made to conform to it, then that 
>>> would work around the problem (I believe I pitched this at some point long 
>>> ago, but without catching any interest).
>>> 
>>> Charles
>>> 
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [draft] Introduce Sequence.filteredMap(_:)

2017-10-23 Thread BJ Homer via swift-evolution
I agree with Xiaodi; I like ‘filterMap’ more than ‘filteredMap’. But both are 
superior to ‘flatMap’ in this context.

-BJ

> On Oct 23, 2017, at 5:22 PM, Max Moiseev <mois...@apple.com> wrote:
> 
> It occurred to me that filteringMap(_:) should be even more descriptive, 
> still conform to the guidelines, although similarly unprecedented and 
> un-googlable.
> 
> Max
> 
>> On Oct 23, 2017, at 3:52 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>> 
>> +1 in general. As to the name: since 'map' is used as a term of art, 
>> 'filterMap' seems superior to 'filteredMap', which half follows naming 
>> guidelines and half is a term of art; neither is immediately comprehensible 
>> but 'filterMap' can be googled and has precedents in other languages.
>> On Mon, Oct 23, 2017 at 17:24 BJ Homer via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>>> I strongly agree! In fact, I just started writing up a similar proposal the 
>>> other day, but hadn’t had time to finish it yet.
>>> 
>>> The current name for this particular filtering variant is not particularly 
>>> descriptive. It’s certainly not obvious to newcomers that ‘flatMap’ will 
>>> filter out results. And it’s not true to the existing usage of ‘flatMap' 
>>> from other languages; you have to really squint at it to see how any 
>>> “flattening” is happening at all.
>>> 
>>> So yes, a big +1 from me. Thanks!
>>> 
>>> -BJ Homer
>>> 
>>>> On Oct 23, 2017, at 4:15 PM, Max Moiseev via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> Hi swift-evolution!
>>>> 
>>>> I would like to propose the following change to the standard library:
>>>> 
>>>> deprecate `Sequence.flatMap(_: (Element) -> U?) -> [U]` and make this 
>>>> functionality available under a new name `Sequence.filteredMap(_:)`.
>>>> 
>>>> The draft is available at 
>>>> https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95 and is 
>>>> included below for your convenience.
>>>> 
>>>> Max
>>>> 
>>>> Introduce Sequence.filteredMap(_:)
>>>> 
>>>> Proposal: SE-
>>>> Authors: Max Moiseev
>>>> Review Manager: TBD
>>>> Status: Awaiting implementation
>>>> Introduction
>>>> 
>>>> We propose to deprecate the controversial version of a Sequence.flatMap 
>>>> method and provide the same functionality under a different, and 
>>>> potentially more descriptive, name.
>>>> 
>>>> Motivation
>>>> 
>>>> The Swift standard library currently defines 3 distinct overloads for 
>>>> flatMap:
>>>> 
>>>> Sequence.flatMap(_: (Element) -> S) -> [S.Element]
>>>> where S : Sequence
>>>> Optional.flatMap(_: (Wrapped) -> U?) -> U?
>>>> Sequence.flatMap(_: (Element) -> U?) -> [U]
>>>> The last one, despite being useful in certain situations, can be (and 
>>>> often is) misused. Consider the following snippet:
>>>> 
>>>> struct Person {
>>>>   var age: Int
>>>>   var name: String
>>>> }
>>>> 
>>>> func getAges(people: [Person]) -> [Int] {
>>>>   return people.flatMap { $0.age }
>>>> }
>>>> What happens inside getNames is: thanks to the implicit promotion to 
>>>> Optional, the result of the closure gets wrapped into a .some, then 
>>>> immediately unwrapped by the implementation of flatMap, and appended to 
>>>> the result array. All this unnecessary wrapping and unwrapping can be 
>>>> easily avoided by just using map instead.
>>>> 
>>>> func getAges(people: [Person]) -> [Int] {
>>>>   return people.map { $0.age }
>>>> }
>>>> It gets even worse when we consider future code modifications, like the 
>>>> one where Swift 4 introduced a Stringconformance to the Collection 
>>>> protocol. The following code used to compile (due to the flatMap overload 
>>>> in question).
>>>> 
>>>> func getNames(people: [Person]) -> [String] {
>>>>   return people.flatMap { $0.name }
>>>> }
>>>> But it no longer does, because now there is a better overload that does 
>>>> not involve implicit promotion. In this particular case, the compiler 
>>>> error would be obvious, a

Re: [swift-evolution] [draft] Introduce Sequence.filteredMap(_:)

2017-10-23 Thread BJ Homer via swift-evolution
I strongly agree! In fact, I just started writing up a similar proposal the 
other day, but hadn’t had time to finish it yet.

The current name for this particular filtering variant is not particularly 
descriptive. It’s certainly not obvious to newcomers that ‘flatMap’ will filter 
out results. And it’s not true to the existing usage of ‘flatMap' from other 
languages; you have to really squint at it to see how any “flattening” is 
happening at all.

So yes, a big +1 from me. Thanks!

-BJ Homer

> On Oct 23, 2017, at 4:15 PM, Max Moiseev via swift-evolution 
>  wrote:
> 
> Hi swift-evolution!
> 
> I would like to propose the following change to the standard library:
> 
> deprecate `Sequence.flatMap(_: (Element) -> U?) -> [U]` and make this 
> functionality available under a new name `Sequence.filteredMap(_:)`.
> 
> The draft is available at 
> https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95 
>  and is 
> included below for your convenience.
> 
> Max
> 
> Introduce Sequence.filteredMap(_:)
> 
> Proposal: SE- 
> Authors: Max Moiseev 
> Review Manager: TBD
> Status: Awaiting implementation
>  
> Introduction
> 
> We propose to deprecate the controversial version of a Sequence.flatMap 
> method and provide the same functionality under a different, and potentially 
> more descriptive, name.
> 
>  
> Motivation
> 
> The Swift standard library currently defines 3 distinct overloads for flatMap:
> 
> Sequence.flatMap(_: (Element) -> S) -> [S.Element]
> where S : Sequence
> Optional.flatMap(_: (Wrapped) -> U?) -> U?
> Sequence.flatMap(_: (Element) -> U?) -> [U]
> The last one, despite being useful in certain situations, can be (and often 
> is) misused. Consider the following snippet:
> 
> struct Person {
>   var age: Int
>   var name: String
> }
> 
> func getAges(people: [Person]) -> [Int] {
>   return people.flatMap { $0.age }
> }
> What happens inside getNames is: thanks to the implicit promotion to 
> Optional, the result of the closure gets wrapped into a .some, then 
> immediately unwrapped by the implementation of flatMap, and appended to the 
> result array. All this unnecessary wrapping and unwrapping can be easily 
> avoided by just using map instead.
> 
> func getAges(people: [Person]) -> [Int] {
>   return people.map { $0.age }
> }
> It gets even worse when we consider future code modifications, like the one 
> where Swift 4 introduced a Stringconformance to the Collection protocol. The 
> following code used to compile (due to the flatMap overload in question).
> 
> func getNames(people: [Person]) -> [String] {
>   return people.flatMap { $0.name }
> }
> But it no longer does, because now there is a better overload that does not 
> involve implicit promotion. In this particular case, the compiler error would 
> be obvious, as it would point at the same line where flatMap is used. Imagine 
> however if it was just a let names = people.flatMap { $0.name } statement, 
> and the names variable were used elsewhere. The compiler error would be 
> misleading.
> 
>  
> Proposed
>  solution
> 
> We propose to deprecate the controversial overload of flatMap and 
> re-introduce the same functionality under a new name. The name being 
> filteredMap(_:) as we believe it best describes the intent of this function.
> 
> For reference, here are the alternative names from other languages:
> 
> Haskell, Idris 
> mapMaybe :: (a -> Maybe b) -> [a] -> [b]
> Ocaml (Core and Batteries)
>  filter_map : 'a t -> f:('a -> 'b option) -> 'b t
> F#
>  List.choose : ('T -> 'U option) -> 'T list -> 'U list
> Rust
>  fn filter_map(self, f: F) -> FilterMap
>  where F: 
> FnMut(Self::Item) -> Option
> Scala 
> def collect[B](pf: PartialFunction[A, B]): List[B]
>  
> Source
>  compatibility
> 
> Since the old function will still be available (although deprecated) all the 
> existing code will compile, producing a deprecation warning and a fix-it.
> 
>  
> Effect
>  on ABI stability
> 
> This is an additive API change, and does not affect ABI stability.
> 
>  
> Effect
>  on API resilience
> 
> Ideally, the deprecated flatMap overload would not exist at the time when ABI 
> stability is declared, but in the worst case, it will be available in a 
> deprecated form from a library post-ABI stability.
> 
>  
> 

Re: [swift-evolution] [Draft] Rename Sequence.elementsEqual

2017-10-16 Thread BJ Homer via swift-evolution
> On Oct 16, 2017, at 8:20 AM, Thorsten Seitz via swift-evolution 
>  wrote:
> 
>> Am 16.10.2017 um 07:19 schrieb Xiaodi Wu > >:
> 
>> What useful generic algorithms would this protocol support that are not 
>> already possible?
> 
> It would allow expressing generic algorithms depending on an order.
> 
> -Thorsten

We can already express generic algorithms that depend on an order—any generic 
algorithm that works on a Sequence works on something that is ordered. A Swift 
Set has an undefined order right now, but a generic algorithm working on any 
arbitrary Sequence likely doesn’t care about what the order, just that an order 
exists. And a Swift Set does indeed have an order. If you have a generic 
algorithm that only works on inputs sorted in a particular manner, then you’ve 
likely either documented that or added a “sortedBy” parameter. Otherwise, you 
probably just want to be able to iterate through everything.

Let’s assume, though, that you wanted to write an algorithm that works only on 
MeaningfullyOrdered inputs. 

func extractInfo(_ input: T) { }
extractInfo(someArray)

What stops the caller from simply wrapping the Set in an Array?

extractInfo(Array(someSet))

The Array constructed here is going to reflect the arbitrary ordering provided 
by Set, but as far as the type system is concerned, the input is an Array, 
which is certainly meaningfully-ordered. Have we gained anything by requiring 
the caller to wrap the input in an array? We’ve made the call site a bit more 
awkward, and we’ve lost a bit of performance. We certainly need to be able to 
convert Sets in to Arrays; to eliminate that would be massively 
source-breaking, and it’s not clear that allowing that conversion is actively 
harmful, so it’s unlikely to change in Swift 5.

So I agree with Xiaodi; I don’t see what we would gain by splitting the 
protocols, other than some conceptual purity. Some have expressed concern over 
the existence of someSet.first, but even if we removed it, it would still be 
available as Array(someSet).first. And we still haven't any examples of actual 
algorithms that would surprise the user by behaving incorrectly when given an 
arbitrarily-ordered sequence, so it’s hard to make the argument that this 
restriction is actively harmful.

I agree that isOrderedEqual(to:) is a better name for elementsEqual()

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


Re: [swift-evolution] [Proposal] implicit `if let`

2017-10-11 Thread BJ Homer via swift-evolution
This has been proposed and rejected a few times, actually. You can see it in 
the Swift-Evolution “Commonly Rejected Changes” document here: 
https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md 


-BJ

> On Oct 11, 2017, at 12:29 PM, Manuel Carrasco Molina via swift-evolution 
>  wrote:
> 
> Hi,
> 
> We usually do this
> 
> If let foo = foo {
> // bar
> }
> 
> What if the compiler would understand
> 
> If let foo {
> // bar
> }
> 
> As if the `= foo` would be there?
> 
> I’d find it great syntactic sugar.
> ___
> 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-04 Thread BJ Homer via swift-evolution
It certainly could break *some* code. But it only breaks code written by an 
author who wrote ‘private extension’ knowing that ‘fileprivate extension’ was 
also an option, but still intended it to be shared with the whole file. (If 
that code was from Swift 2, it would have already been migrated to ‘fileprivate 
extension’ by the 2->3 migrator.)

So existing code that says ‘private extension’ was written in a Swift 3 or 4 
era when ‘fileprivate’ was an option. If the goal was specifically to share it 
with the whole file, it seems likely that most authors would have used 
‘fileprivate extension’ instead of ‘private extension’, as that better 
communicates the intention. Regardless, though, we could check against the 
Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I’m in favor 
of it.

-BJ

> On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution 
>  wrote:
> 
> 
> 
>> On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
 On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution 
  wrote:
 
 
 Sent from my iPad
 
> On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>> On 01.10.2017 1:18, Chris Lattner wrote:
 On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution 
  wrote:
 
 Vladimir, I agree with you on that change, but it’s a separate topic 
 from this one.
 
 Tony is absolutely correct that this topic has already been discussed. 
 It is a deliberate design decision that public types do not 
 automatically expose members without explicit access modifiers; this 
 has been brought up on this list, and it is clearly not in scope for 
 discussion as no new insight can arise this late in the game. The 
 inconsistency with public extensions was brought up, the proposed 
 solution was to remove modifiers for extensions, but this proposal was 
 rejected. So, the final design is what we have.
>>> Agreed.  The core team would only consider a refinement or change to 
>>> access control if there were something actively broken that mattered 
>>> for ABI stability.
>> 
>> So we have to live with *protected* extension inconsistency for very 
>> long time just because core team don't want to even discuss _this 
>> particular_ inconsistency(when access level in *private extension* must 
>> be private, not fileprivate)?
>> 
>> Yes, we decided that access level for extension will mean a default and 
>> top most access level for nested methods, OK. But even in this rule, 
>> which already differ from access modifiers for types, we have another 
>> one special case for 'private extension'.
>> 
>> Don't you think this is not normal situation and actually there IMO 
>> can't be any reason to keep this bug-producing inconsistency in Swift? 
>> (especially given Swift 5 seems like is a last moment to fix this)
> 
> I hate to say it but I'm inclined to agree with Vladimir on this. 
> "private extension" has a useful meaning now distinct from "fileprivate 
> extension", and it was an oversight that SE-0169 didn't include a fix 
> here. On this very narrow, very specific access control issue I think it 
> would still be worth discussing; like Xiaodi said it's not related to 
> James' original thread-starter.
 
 I agree with this in principle but would not want to see it become a 
 slippery slope back into extremely long access control discussions.
 
>>> 
>>> As I've said elsewhere, I too agree with this in principle. I agree with 
>>> Jordan that the current state of things is justifiable but the alternative 
>>> would be somewhat superior, agree that in a vacuum this very narrow and 
>>> specific discussion might be warranted, and agree also that this could be a 
>>> very slippery slide down a very steep slope.
>> 
>> Same here. It’s the only grudge I have left with the current access control 
>> situation. I remember Doug Gregor and John McCall discussing this during the 
>> last access control proposal. And I wouldn’t mind having a very narrow 
>> discussion about only this.
>> 
>> I organize my types into extensions for each conformance and for each access 
>> control. I can currently implicitly apply public or fileprivate to all 
>> members of an extension but I have no way of doing the same for private. 
>> That’s why I think it should be 

Re: [swift-evolution] Enums and Source Compatibility

2017-09-17 Thread BJ Homer via swift-evolution
Please note that, as proposed, enums are always treated as exhaustive *within 
the same module*. A new user writing MyFirstEnum is likely using it within the 
same module, and will thus get exhaustive behavior with no extra keywords 
required.

-BJ

> On Sep 17, 2017, at 3:20 PM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> 
>>> On Sep 17, 2017, at 6:33 AM, Rod Brown via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On 17 Sep 2017, at 4:35 am, Christopher Kornher  wrote:
 
 On Sep 16, 2017, at 11:28 AM, Christopher Kornher via swift-evolution 
  wrote:
 
 If a library writer can’t remember to declare non-exhaustive enums as 
 such, they probably will forget many more important aspects of creating a 
 library. They probably should not be writing libraries. Arguments like 
 this make sense on the surface, but creating libraries involves hundreds 
 or thousands of decisions. I wish you luck in making that process idiot 
 proof. A library linter could easily warn that exposed enums are 
 exhaustive. The exhaustive keyword should be optional to make the decision 
 obvious and suppress warnings. Complicating the user experience in a vain 
 attempt to make “expert" coding safer is misguided.
>> 
>> I think the same logic goes both ways: If a library author can’t remember to 
>> declare exhaustive enums as such, they will probably forget many more 
>> important aspects of creating a library.
>> 
>> The problem here is fundamental: Exhaustive is a guarantee. A guarantee 
>> should require action. Non-Exhaustive guarantees nothing. It makes you 
>> safer. That is all.
> 
> 1) Exhaustive enums are inherently better: they allow a developer to know 
> that they have covered all possible cases by not using a default.
> 2) This proposal forces developers to add a keyword to get this behavior in 
> their apps, which is common to all other languages with enums that I have 
> used. This proposal breaks the model common to all (?) current 
> implementations of enums. 
> 
> 
>> 
>>> 
>>> This may be a little harsh, but there don’t seem to be many advocates for 
>>> novice and “ordinary” application developers on this list. That is not 
>>> unexpected given the number of extremely knowledgeable compiler and library 
>>> developers on this list (for whom I have the highest respect). I believe 
>>> that there are more creative (and probably more difficult to build) 
>>> possible solutions to some of the tough problems in Swift’s future. In that 
>>> spirit, see below.
>> 
>> I personally am an “ordinary” application developer.
>> 
>> I think the issue here is that everyone is seeing Swift as *they* intend to 
>> use it. For App Devs, exhaustive switches are nice, which means they really 
>> are fighting tooth and nail to keep them. I understand that. But I’m also 
>> trying to keep my mind open for “what happens to an app I compiled in iOS 15 
>> that I compiled for iOS 11?” And this gives me pause. I can’t ask Apple or 
>> any other library author to be completely knowledgable about every case in 
>> the future, and to audit every line of code and manually give non-exhaustive.
>> 
>> Why do people want “exhaustive” to be the default?
>> Because we like things as they are.
> 
> No, because it makes sense to make common things easy and uncommon things 
> possible. 
> 
>> Because we like not having to consider edge cases. Because we want to 
>> imagine that will give framework developers the control to make our lives 
>> difficult because they’ll just be lazy and make our lives hard by not 
>> annotating. And this certainly is a concern. But I think a larger concern is 
>> breaking apps left, right and centre, or not being able to extend frameworks 
>> because an earlier developer on a project made an oversight.
> 
> This happens all the time: Apple deprecates APIs and asked developers to use 
> new ones. If a library writer does not run (the as-yet hypothetical ) library 
> lint, not participate in thorough code reviews,…, they can simply create a 
> new non-exhaustive enum and deprecate the old one. Yes, there will be some 
> redundant function calls for a while, but again, similar things happen, even 
> in APIs like Apple’s, that (one hopes, at least) are thoroughly reviewed. It 
> is not the end of the world to deprecate and migrate APIs. You  may remember 
> garbage collected Objective-C, the change that “viewWillAppear” suddenly was 
> not called when it used to be in iOS. We all survived the elimination of GC 
> and moving our view initialization code. Libraries and developers can survive 
> mistakes and improvements.
> 
> ABI stability does not require foolproof, immutable, ABIs. In essence, it is 
> just a guarantee that the build system won’t require rebuilds if library 
> source code stays the same, or is added to, not that applications will never 
> have to be 

Re: [swift-evolution] [Concurrency] A slightly different perspective

2017-09-03 Thread BJ Homer via swift-evolution
Okay, that's an interesting proposal. I'm not qualified to judge how big of a 
win the compiler optimizations would be there; I'm a little skeptical, but I 
admit a lack of expertise there. It seems like it's not essential to the core 
'async/await' proposal, though; it could be added later with no source 
breakage, and in the meantime we can accomplish most of the same behavior 
through an explicit Future type. I think it makes more sense to consider the 
base proposal before adding more complexity to it.

-BJ

> On Sep 3, 2017, at 10:15 PM, Jonathan Hull  wrote:
> 
> 
>> On Sep 3, 2017, at 7:35 PM, BJ Homer  wrote:
>> 
>> Jonathan,
>> 
>> You've mentioned the desire to have 'async' defer calling 'await', but I 
>> haven't seen a detailed design yet.
> Oh, we discussed it awhile back on a few other threads.  I am happy to help 
> write up a more formal/detailed design if there is enough interest...
> 
>> For example, is the following code valid?
>> 
>>   let image = async fetchImage()
>>   let image2 = async fetchImage()
>>   let deferredThings = [image1, image2]
>> 
>> If so, what is the type of 'deferredThings'? And how does it not count as 
>> 'using' the values.
> 
> No this code is not valid.  You would need to ‘await’ both image 1 & 2 before 
> they could be put in an array or transferred to another variable. You could 
> combine the ‘await’s though (similar to try):
> 
>   let image = async fetchImage()
>   let image2 = async fetchImage()
>   let deferredThings = await [image1, image2]
> 
> 
> Note: You can return something which is deferred from an async function 
> without awaiting though...
> 
> 
>> If the above code is not valid, how is this situation better than the 
>> suggested use of a Future type to allow concurrent async requests?
>> 
>>   let future1 = Future { await fetchImage() }
>>   let future2 = Future { await fetchImage() }
>>   let deferredThings = [future1, future2]
>> 
>> Note that in this example, 'deferredThings' has a concrete type, and we can 
>> inspect its values.
> 
> It isn’t meant to be used instead of Futures (though you may not need to 
> reach for them as often), it is a much lower-level construct which would be 
> used as a building block for things like futures (and other concurrency 
> constructs).
> 
> Because there is no way for the programmer to get at the thing being 
> ‘await’ed (or any representation of it) without awaiting on it, and it can’t 
> escape the context, it gives the compiler some extra guarantees that it can 
> use to optimize things behind the scenes. Even if the compiler just ends up 
> creating a future behind the scenes, that implementation is completely hidden 
> to the programmer, and can be updated/changed at any time by the compiler 
> team without involving evolution.
> 
> Let’s say at some point down the road as part of the actor work, the compiler 
> ends up getting some visibility into how actor queues will be coalesced… Then 
> it can use that knowledge to reorganize the code above to be more efficient.  
> For example, if it knows that the part of the calls to fetchImage() will be 
> serialized by an actor, it can just make that part synchronous and avoid the 
> asynchronous overhead.  If we had baked in everything at the low-level to use 
> future objects, we wouldn’t be able to make that optimization.
> 
> There are 2 big results from this:
> 
> 1) It gives us the ability to easily start several things behind the scenes 
> and then await the group of them finishing
> 
> 2) Our implementation of Futures (and other constructs) can potentially take 
> advantage of the compiler optimizations by using this beneath the hood.
> 
> 
> The first point is huge for me. This is an extremely common thing to want in 
> real-world code, but it usually requires a bunch of complex (sometimes 
> error-prone) machinery to actually pull off. There is often wasted overhead 
> as well.  I like that I can do it here in a very natural and lightweight way. 
>  (Futures also simplify this problem a great deal, but I wouldn’t really call 
> them lightweight). 
> 
> 
>> You keep bringing up this suggestion, so I must be missing something, but it 
>> seems to me that your suggestion is covered by Futures. Why is calling with 
>> 'async' better?
> 
> As I said above, I think this will help our Futures be much more efficient 
> when we build them, but there are also some advantages of having this as an 
> option and not just using Futures for everything.
> 
> Mainly, futures require a different return type, and they require 
> boxing/unboxing.  To chain futures, each link in the chain has to be 
> future-aware… and each link can only be used with futures (i.e. the return 
> type is Future).  There are a lot of cases where I am boxing just to 
> unbox and re-box.  Most of that is fine as long as the framework was built 
> with it in mind, but it doesn’t work as well if I want to add the 
> functionality post-hoc.

Re: [swift-evolution] [Concurrency] A slightly different perspective

2017-09-03 Thread BJ Homer via swift-evolution
Jonathan,

You've mentioned the desire to have 'async' defer calling 'await', but I 
haven't seen a detailed design yet. For example, is the following code valid?

  let image = async fetchImage()
  let image2 = async fetchImage()
  let deferredThings = [image1, image2]

If so, what is the type of 'deferredThings'? And how does it not count as 
'using' the values.

If the above code is not valid, how is this situation better than the suggested 
use of a Future type to allow concurrent async requests?

  let future1 = Future { await fetchImage() }
  let future2 = Future { await fetchImage() }
  let deferredThings = [future1, future2]

Note that in this example, 'deferredThings' has a concrete type, and we can 
inspect its values.

You keep bringing up this suggestion, so I must be missing something, but it 
seems to me that your suggestion is covered by Futures. Why is calling with 
'async' better?

-BJ

> On Sep 3, 2017, at 6:01 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> 
>>> On Sep 3, 2017, at 9:04 AM, Chris Lattner via swift-evolution 
>>>  wrote:
 On Sep 3, 2017, at 4:00 AM, David Hart  wrote:
 Please don’t read too much into the beginAsync API.  It is merely a 
 strawman, and intended to be a low-level API that higher level 
 abstractions (like a decent futures API) can be built on top of.  I think 
 it is important to have some sort of primitive low-level API that is 
 independent of higher level abstractions like Futures.
 
 This is all a way of saying “yes, having something like you propose makes 
 sense” but that it should be part of the Futures API, which is outside the 
 scope of the async/await proposal.
>>> 
>>> But it would be nice for all high-level APIs that conform to a Awaitable 
>>> protocol to be used with await without having to reach for a get property 
>>> or something similar everytime.
>> 
>> The futures API that is outlined in the proposal is just an example, it 
>> isn’t a concrete pitch for a specific API.  There are a bunch of 
>> improvements that can (and should) be made to it, it is just that a futures 
>> API should be the subject of a follow-on proposal to the basic async/await 
>> mechanics.
> 
> Would it be possible to have the manifesto be a series of proposals then?  I 
> really think it is important for us to look at how all of these things fit 
> together.  I agree that async/await should come first, but looking at how 
> concrete things like Futures would work may help to inform the design of 
> async/await.  We should do the back-propigation in our design before anything 
> is locked in...
> 
> The thing I would most like to see as a quick follow-on to async/await is the 
> ability to use the ‘async’ keyword to defer ‘await’. This feels very natural, 
> is highly optimizable by the compiler, and it allows for a lot of very common 
> use-cases which are not covered well by pure async/await.  I think it would 
> have a large impact on the eventual design/implementation of futures (and at 
> least some impact on the design of async/await).
> 
> Thanks,
> Jon
> ___
> 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] New async keyword usage

2017-08-25 Thread BJ Homer via swift-evolution
> I'm not sure why it's understood as all or nothing, AFAICU, await is just a 
> way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.

Await does not block the current queue. You can imagine that it gathers up the 
rest of the function after the ‘await’ line and moves it into a callback. That 
is, it turns this:

let x = await somethingThatTakesALongTime()
print(“Congratulations, we got x”)
print(“x: \(x)”)

into something like this:

somethingThatTakesALongTime(completion: { (x) in
   print(“Congratulations, we got x”)
   print(“x: \(x)”)
})

It does not block the current queue, though. The current queue keeps going on 
with whatever it was doing before. When the ‘await'ed call finished, it is 
scheduled back on a queue to continue running.

-BJ

> On Aug 25, 2017, at 4:39 PM, Florent Vilmart via swift-evolution 
>  wrote:
> 
> 
> On 25 août 2017 18:31 -0400, Jonathan Hull , wrote:
>> But then it would need to be called with await under the current proposal, 
>> meaning that either:
>> 
>> • b would await the calculation of a
>> 
>> beginAsync {
>> let a = await longCalculationA()
>> let b = await longCalculationB() //This only calculates when a is finished
>> } 
> why would it? the async modifier could very well be used to transform a sync 
> function into an async one, dispatching on a defined queue returning the 
> 'Future' and resolving once the function completes.
> 
> I'm not sure why it's understood as all or nothing, AFAICU, await is just a 
> way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.
> 
> something like
> 
> let a = await async longSynchrounousCall() would block the current execution 
> queue (because await) but the execution of the longSynchronousCall() would be 
> on a separate queue / block.
> 
> The question lays more in where the calls are executed, either they are 
> dispatched after, current block is suspended, runloop continues, and then the 
> block is re-entered upon returning.  that would lead to some weird executions 
> flows.
> 
>> 
>> • or b would be executed while a is awaiting, but a and b would be in 
>> different scopes
>> 
>> beginAsync{
>> let a = await longCalculationA()
>> }
>> beginAsync{
>> let b = await longCalculationB() //We can’t see ‘a’ anymore
>> }
>> //We can’t see ‘a’ or ‘b’ here to use them
>> 
>> We could, also implement some sort of future, and then re-write our 
>> functions to take advantage of it, but this misses out on numerous compiler 
>> optimizations and requires our functions to be written with futures in mind. 
>>  In my example, the functions can just be written as async, and they don’t 
>> care whether they are called with async or await.
>> 
>> Thanks,
>> Jon
>> 
>>> On Aug 25, 2017, at 3:13 PM, Florent Vilmart >> > wrote:
>>> 
>>> be doesn't wait if it's defined as 
>>> 
>>> func longCalculationB() async -> SomeType 
>>> 
>>> which would be helpful if it's a long calculation, 
>>> 
>>> in the case it's
>>> 
>>> func longCalculationB() -> SomeType 
>>> 
>>> That would probably be valid to put the async keyword front even though I 
>>> would not be a big fan of that as you'd be executing on an indefinite queue 
>>> a calculation that may not be thread safe.
>>> 
>>> async would be in that case a wrapper around dispatch_async  + semaphore
>>> 
>>> 
>>> On 25 août 2017 18:08 -0400, Jonathan Hull >> >, wrote:
 Why wouldn’t b wait for a in this example?  If it is using futures, those 
 aren’t available in the current proposal.
 
> On Aug 25, 2017, at 3:02 PM, Florent Vilmart  > wrote:
> 
> Probably with:
> 
> let a = longCalculationA() 
> let b = longCalculationB() //b doesn’t wait for a to complete before 
> starting
> let c = longCalculationC() //c doesn’t wait for a or b
> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits 
> until a, b, and c are all available
> 
> On 25 août 2017 17:48 -0400, wrote:
>> 
>> let a = async longCalculationA()
>> let b = async longCalculationB() //b doesn’t wait for a to complete 
>> before starting
>> let c = async longCalculationC() //c doesn’t wait for a or b
>> let result = await combineCalculations(a: a, b: b, c: c) //waits until 
>> a, b, and c are all available
 
>> 
> ___
> 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] New async keyword usage

2017-08-25 Thread BJ Homer via swift-evolution
> how would you accomplish the following under the current proposal?


We could implement a Future type (as imagined in the async/await proposal), 
which would enable something like this:

let futureA = Future { await longCalculationA() }
let futureB = Future { await longCalculationB() }
let futureC = Future { await longCalculationC() }

// Asynchronously waits for a, b, and c to finish before calling 
combineCalculations()
let result = await combineCalculations(a: a.get(), b: b.get(), c: 
c.get()) 

If there's no Future type around, it's reasonable to imagine that 
DispatchQueue.async would be modified to accept an 'async' closure, so you 
could do this:

let group = DispatchGroup()
let queue = DisatchQueue.global()

var a: Any? = nil
var b: Any? = nil
var c: Any? = nil

group.enter()
queue.async {
a = await longCalculationA()
group.leave()
}

group.enter()
queue.async {
b = await longCalculationB()
group.leave()
}

group.enter()
queue.async {
c = await longCalculationC()
group.leave()
}

group.notify {
combineCalculations(a: a, b: b, c: c)
}

A Future type certainly makes this look nicer, though.

-BJ

> On Aug 25, 2017, at 3:49 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> To prove (or potentially disprove) my assertion that this is not just sugar, 
> how would you accomplish the following under the current proposal?
> 
>   let a = async longCalculationA()
>   let b = async longCalculationB() //b doesn’t wait for a to complete 
> before starting
>   let c = async longCalculationC() //c doesn’t wait for a or b
>   let result = await combineCalculations(a: a, b: b, c: c) //waits until 
> a, b, and c are all available
> 
> (Note: this is using my version of async below which doesn’t use futures)
> 
> Thanks,
> Jon
> 
> 
>> On Aug 25, 2017, at 2:13 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>> I actually really like the idea of using ‘async' to start a computation in a 
>> non-blocking way.  It is extremely common in real-world code to want to 
>> start a few computations/downloads at once in the background and then use 
>> the results together...
>> 
>> I think full-fledged futures could be a framework thing added on top, but 
>> what I would really love to see at the language level is that using ‘async’ 
>> just allows you to defer calling ‘await’.  That is, you could get a value 
>> back from something called with async, but you would be forced to await that 
>> value before it could be used:
>> 
>>  var image = async downloadImage()  //Image is type UIImage
>>  //Do something else here
>>  let size = await image.size //The compiler forces me to call await 
>> before I can actually use the value
>> 
>> This looks somewhat similar to a future, but you can’t interact with it as a 
>> separate type of object.  The value above is just a UIImage, but with a 
>> compiler flag/annotation that forces me to call await on it before it can be 
>> accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
>> things behind the scenes, because it doesn’t necessarily need to make an 
>> intermediate object.
>> 
>> I don’t think this is just sugar.  It adds expressivity and control for a 
>> set of very common use-cases which aren’t fully supported by await alone.
>> 
>> Thanks,
>> Jon
>> 
>> 
>>> On Aug 24, 2017, at 4:40 AM, Trevör ANNE DENISE via swift-evolution 
>>> > wrote:
>>> 
>>> Hello Swift community,
>>> 
>>> I was really interested by the recent Task-based concurrency manifesto and 
>>> Concrete proposal for async semantics in Swift.
>>> 
>>> Looking at beginAsync() and Futures, I had an idea for a new syntax based 
>>> on the `async` keyword, I'd love to hear your feedback about this idea:
>>> https://github.com/adtrevor/Swift-ideas/blob/master/New%20async%20keyword%20usage.md
>>>  
>>> 
>>> 
>>> Would such a syntax make any sense?
>>> 
>>> Thank you ! :)
>>> 
>>> 
>>> Trevör
>>> ___
>>> 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 

Re: [swift-evolution] [Concurrency] Async/Await

2017-08-24 Thread BJ Homer via swift-evolution
Your processImageData1() function is not asynchronous, and does not need to 
return a future, because the “.get” calls are blocking; as you have implemented 
them, they will wait until they have a response or timeout. As a result, by the 
time you reach the return imageResult line, you have already waited for that 
data (or timed out), with the current thread blocked. There is no work left to 
do in the Future.

The point of async/await is that we can wait for the completion of those items 
asynchronously, not blocking the current thread. The control would return to 
the calling function before all the data was fetched.

-BJ

> On Aug 23, 2017, at 7:35 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Hi All,
> 
> Really glad that concurrency is on the table for Swift 5.
> 
> I am not sure if async/await are worth adding, as is, to Swift because it is 
> just as easy to do with a library function - in the spirit of Swift 5, see 
> `Future` library code below that you can play with and run.
> 
> If a `Future` class was added and the compiler translated 
> 'completion-handler' code to 'future' code then the running example given in 
> the whitepaper would become (also see the example in the code below):
> 
> func loadWebResource(_ path: String) -> Future { ... }
> func decodeImage(_ dataResource: Resource, _ imageResource: Resource) -> 
> Future { ... }
> func dewarpAndCleanupImage(_ image: Image) -> Future { ... }
> 
> func processImageData1() -> Future {
> let dataResource  = loadWebResource("dataprofile.txt") // dataResource 
> and imageResource run in parallel.
> let imageResource = loadWebResource("imagedata.dat")
> let imageTmp  = decodeImage(dataResource.get ?? Resource(path: 
> "Default data resource or prompt user"), imageResource.get ?? Resource(path: 
> "Default image resource or prompt user"))
> let imageResult   =  dewarpAndCleanupImage(imageTmp.get ?? 
> Image(dataPath: "Default image or prompt user", imagePath: "Default image or 
> prompt user"))
> return imageResult
> }
>  
> Which I would argue is actually better than the proposed async/await code 
> because:
> The code is naturally parallel, in example dataResource and imageResource are 
> calculated in parallel. 
> The code handles errors and deadlocks by providing a default value using `??`.
> The code can be deadlock free or can help find deadlocks, see code below, due 
> to having a timeout and a means of cancelling.
> The programmer who writes the creator of the `Future` controls which queue 
> the future executes on, I would contend that this is the best choice since 
> the programmer knows what limitations are in the code and can change queue if 
> the code changes in later versions. This is the same argument as 
> encapsulation, which gives more control to the writer of a struct/class and 
> less control to the user of the struct/class.
> In summary, I don't think async/await carries its weight (pun intended), as 
> it stands, compared to a library.
> 
> But definitely for more Swift concurrency,
> 
>  -- Howard.
> 
> PS A memory model and atomic that also guaranteed volatile would really help 
> with parallel programming!
> 
> …(snip)...
> ___
> 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] KeyPath based map, flatMap, filter

2017-07-11 Thread BJ Homer via swift-evolution
‘$' as a prefix is reserved for use by the debugger, so it cannot be used as a 
conversion operator here.

-BJ

> On Jul 11, 2017, at 10:12 AM, Robert Bennett via swift-evolution 
>  wrote:
> 
> It seems that there is some consensus that the proper way to achieve this is 
> not to overload map et al. but to provide a way to convert KeyPath to a 
> function. I agree – not only is this “cheaper”, as overloads of these 
> functions will not need to be written, but it’s also more general and may 
> prove useful in a context that we currently don’t foresee.
> 
> This being the case, I’ll repeat my proposal that the optimal way to achieve 
> this is to make $ the conversion “operator” (although it need not, and 
> probably should not, be a full-fledged operator), so that $keyPath –> { 
> $0[keyPath: keyPath] }
> 
> On Jul 11, 2017, at 11:13 AM, Elviro Rocca via swift-evolution 
> > wrote:
> 
>> Overloads are ugly. The very existence of an overloaded function usually 
>> means a lack of available abstractions, or an insufficient abstraction power 
>> in the language: exhibit A is conditional conformances to protocols.
>> 
>> Overloads are particularly ugly if the overloaded function's input 
>> represents basically the same thing: a KeyPath is really (semantically) 
>> just a couple of functions, that is, (A) -> B and (inout A,B) -> (), so the 
>> (A) -> B is already there, and I like the idea of an "extraction" operator 
>> that was proposed in the thread. It would be really interesting to just use 
>> the KeyPath itself wherever a (A) -> B is required, but this looks like 
>> a hack given the current state of Swift's type system.
>> 
>> But I like the fundamental idea behind the proposal: KeyPaths give Swift a 
>> boost in expressive power, and there's probably plenty of use cases that 
>> will emerge in the future.
>> 
>> Thanks
>> 
>> 
>> Elviro
>> 
>>> Il giorno 05 lug 2017, alle ore 19:08, Benjamin Herzog via swift-evolution 
>>> > ha scritto:
>>> 
>>> Hey guys,
>>> 
>>> I would like to pitch a small convenient change to the Swift stdlib. With 
>>> KeyPaths added in SE-0161 I would like to add some convenience calls to 
>>> map, flatMap and filter in Sequences. To extract properties of an array of 
>>> objects we currently use trailing closure syntax together with the 
>>> shorthand $0 for the first closure argument. This is still kind of verbose 
>>> and also hard to read in some situations.
>>> I think it is much better to understand what is going on when using the 
>>> type safe KeyPaths for that. I already implemented a working solution and 
>>> would like to pitch the idea here to get some feedback before opening the 
>>> swift evolution proposal.
>>> I propose using 
>>> 
>>> persons.flatMap(keyPath: \.name)
>>> 
>>> over
>>> 
>>> persons.flatMap { $0.name }
>>> 
>>> Link to pull request: https://github.com/apple/swift/pull/10760 
>>> 
>>> 
>>> Link to proposal draft: 
>>> https://github.com/BenchR267/swift-evolution/blob/keypath-based-map/proposals/0181-keypath-based-map-flatmap-filter.md
>>>  
>>> 
>>> 
>>> Thanks in advance for your feedback!
>>> __
>>> 
>>> Benjamin Herzog
>>> 
>>> ___
>>> 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] [Pitch] Enumerate from offset

2017-05-10 Thread BJ Homer via swift-evolution
I don't see the motivation for removing enumerated(). It's a source-breaking 
change that seems unjustified to me. Sure, enumerated() isn't as flexible as 
one might like, and you can certainly reproduce its effects with zip(), but I 
don't think we've demonstrated that enumerated() is actively harmful. Removing 
it means obsolescing a bunch of training material, blog posts, etc. What do we 
gain by removing it?

-BJ

> On May 10, 2017, at 7:24 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> When this was previously brought up, I believe the consensus was for removing 
> enumerated and doing nothing else.
>> On Wed, May 10, 2017 at 02:50 Pavol Vaskovic  wrote:
>> One more note:
>> 
>>> On Sun, May 7, 2017 at 8:51 PM, Ben Cohen  wrote:
>> 
>>> 
>>> let words = ["five","four","three","two","one","blastoff!"]
>>> ((0...5).reversed() |> { zip($0, words) })
>>> .forEach { print($0.0,$0.1, separator: ": ") }
>>> 
>> 
>>> ...
>> 
>>> 
>>> ((0...5).reversed() |> zip(_, words))
>>> .forEach { print($0.0,$0.1, separator: ": ") }
>> 
>> 
>> The code above demonstrates that replacing `enumerated` with `zip` gives you 
>> anonymous tuples that need to be accessed with positional properties.
>> 
>> In contrast, the tuple returned from `enumerated` gives you named tuple 
>> (offset: Int, element: Element).
>> 
>> Does this change your opinion when you take into account the sorry state of 
>> tuple handling in Swift 4, that prevents you from writing concise and 
>> readable functional code? See:
>> 
>> SR-4745 for (index, (a, b)) in dict.enumerated() produces an error
>> https://bugs.swift.org/browse/SR-4745
>> 
>> SR-4738 Can not decompose nested tuple in closure arguments
>> https://bugs.swift.org/browse/SR-4738
>> 
>> Best regards
>> Pavol Vaskovic 
> ___
> 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: Omit deprecation warnings for same-file references

2017-05-05 Thread BJ Homer via swift-evolution

> On May 5, 2017, at 1:34 PM, Xiaodi Wu  wrote:
> 
> Why guess as to which of these is appropriate? Couldn't you support the 
> current and all variants of this behavior by allowing access modifiers on 
> 'deprecated'?
> 
> * public deprecated: warning when used from a different module, behaves as 
> though there's a public deprecated pass-through
> 
> * internal deprecated: warning when used from a different file
> 
> * fileprivate deprecated: warning when used from a different scope
> 
> * private deprecated: synonymous with deprecated for backwards compatibility, 
> behaves like it does today
> 
> (No need for complicated parsing; SE-25 allows a higher nominal access 
> modifier inside a lower one without warning, so it's fine to allow 'public 
> deprecated' to decorate a private member with no effect.)

I’m not opposed to more configurability like that. I worry it makes the feature 
more complicated and potentially delays the acceptance or implementation of 
this feature, though. If it’s easy to implement, though, then sure, I like that.

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


Re: [swift-evolution] Pitch: Omit deprecation warnings for same-file references

2017-05-05 Thread BJ Homer via swift-evolution
I’ve run into this problem as well, when dealing with legacy file formats 
(similar to the example in the proposal), and I agree it would be nice to be 
able to address it. We’ve got a few “permanent” warnings in our code base right 
now due to this. I’m not sure whether the deprecation should be disabled for 
the entire file, though; perhaps it should be disabled just within the type 
itself? I don’t know how that would contribute to the complexity of the 
implementation, but it seems like we would still want to warn about deprecated 
accesses between two types declared in the same file.

-BJ Homer

> On May 5, 2017, at 12:12 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> Hey Swift Evolvers,
> 
> I'd like to propose a change that would suppress deprecation warnings when 
> the reference to the deprecated declaration is in the same file as that 
> declaration.
> 
> This personally affects one of my projects (Swift protocol buffers) because 
> .proto files allow declarations to be declared as deprecated, and we'd like 
> to surface that by deprecating the equivalent declaration in the Swift code 
> that we generate. We can't do this without generating noisy build logs, 
> because we still need to reference the deprecated declarations to 
> encode/decode the messages correctly; and the workarounds have significant 
> performance penalties as described in the draft.
> 
> I'd love some feedback from folks to know whether this—or something like 
> it—is something that seems desirable/undesirable for the language. I've 
> tinkered with an implementation in a branch 
> 
>  and it's fairly straightforward.
> 
> Gist link: https://gist.github.com/allevato/76f098a761147f3be5017d10a6f4ecbb 
> 
> 
> 
> Omit deprecation warnings for same-file references
> 
> Proposal: SE- 
> 
> Author(s): Tony Allevato 
> Status: Awaiting review 
> 
> Review manager: TBD
>  
> Introduction
> 
> Public API developers can use the @available attribute in Swift to mark APIs 
> as deprecated, which will emit warnings when a user references that API to 
> notify them that that particular API is no longer preferred or may disappear 
> in the future.
> 
> These warnings are emitted for any reference to a deprecated entity, 
> including those in the same file. In some cases, however, it may be necessary 
> and correct to continue referring to the deprecated entity privately while 
> discouraging its external use. In these scenarios, the warnings are 
> superfluous and generate noise in the build logs. We propose eliminating 
> these warnings for references made in the same file.
> 
> Swift-evolution thread: TBD 
> 
>  
> Motivation
> 
> As APIs evolve, declarations may become deprecated but still need to be 
> referenced privately in order to function correctly. For example, consider an 
> object that is serialized/parsed between a client and server. The first 
> iteration of such a type might look like this (the examples use a strawman 
> API to avoid tying the discussion too closely with the new coding APIs, which 
> is not the focus):
> 
> public class Person {
>   public var name: String
>   public var phoneNumber: String?
> 
>   public init(name: String, phoneNumber: String? = nil) {
> self.name = name
> self.phoneNumber = phoneNumber
>   }
> 
>   public convenience init?(from reader: Reader) {
> guard let name = reader.readString(withKey: "name") else {
>   return nil
> }
> let phoneNumber = reader.readString(withKey: "phoneNumber")
> self.init(name: name, phoneNumber: phoneNumber)
>   }
> 
>   public func write(to writer: Writer) {
> writer.write(name, key: "name")
> if let phoneNumber = phoneNumber {
>   writer.write(phoneNumber, key: "phoneNumber")
> }
>   }
> }
> Later, we decide that we need to support storing multiple phone numbers for a 
> Person. To avoid breaking source compatibility, we deprecate the old property 
> and add a new one. We still wish the encoding/decoding process to preserve 
> the integrity of the old data, however—for example, a middleman process used 
> for logging should not modify the data stream, so the encoding/decoding 
> process should not be also migrating the data. Thus, we update the class to 
> the following:
> 
> public class Person {
>   public var name: String
>   @available(*, deprecated, message: "use 'phoneNumbers' instead")
>   public var phoneNumber: String?
>   public 

Re: [swift-evolution] [Pitch] Enumerate from offset

2017-05-04 Thread BJ Homer via swift-evolution
On May 4, 2017, at 8:51 AM, André Videla via swift-evolution 
 wrote:
> 
> You can do this trivially with drop. But enumerated from has one nice 
> property:
> 
> myArray.enumerated().dropFirst(6) // counts from 6
> 
> myArray.dropFirst(6).enumerated() // counts from 0
> 
> Those two lines do very different things even though they look similar

Neither of those does what the proposed enumerated(from:) does, if I understand 
correctly:

let a = [1, 2, 3, 4, 5]
let result = a.enumerated().dropFirst(2)
/*
 (offset: 2, element: 3)
 (offset: 3, element: 4)
 (offset: 4, element: 5)

 */

let result2 = a.dropFirst(2).enumerated()
/*
 (offset: 0, element: 3)
 (offset: 1, element: 4)
 (offset: 2, element: 5)
 */


let proposed = a.enumerated(from: 2)
/*
 (offset: 2, element: 1)
 (offset: 3, element: 2)
 (offset: 4, element: 3)
 (offset: 5, element: 4)
 (offset: 6, element: 5)
 */
The enumerated(from:) name is not clear; it reads (to me) like it’s going to 
enumerate elements starting at the Nth element. What it actually does (as 
proposed) is start counting at N, instead of counting at 0. 

I’m not convinced this is a valuable addition to the language. The use cases 
are not widely applicable, and if you need it it’s easy to get the same results 
in a way that avoids the confusion.

let a = [1, 2, 3, 4, 5]

let result = a.enumerated().map { (idx, element) in
return (idx+2, element)
}

// OR

for (idx, element) in a.enumerated() {
let offsetIndex = idx + 2
// Use offsetIndex how you will
}


-BJ___
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-21 Thread BJ Homer via swift-evolution
The "Access Control" section of the Swift 3 book says the following:
> You can mark an extension with an explicit access-level modifier (for 
> example, private extension) to set a new default access level for all members 
> defined within the extension.
The behavior of "private extension" in Swift 3 was a deviation from that model, 
justified because "private" as a default would have meant that nothing in the 
extension could ever be called. But it was still contrary to the model 
suggested by the Swift documentation. 

Given the highly restrictive behavior of "private" in Swift 3 and the 
documentation quoted above, it seems unlikely that a developer would 
intentionally use "private extension" to mean "please make all this stuff 
visible to the entire file"—it would have worked, but it seems an odd way to 
write it. If that were the intention, I think "fileprivate extension" would 
have been more likely.

I think the change to the behavior of "private extension" is in line with the 
model proposed by SE-0169, in line with the documented behavior of access 
control on extensions, and in line with user expectations.

-BJ

> On Apr 21, 2017, at 9:30 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
> 
>>> On Apr 20, 2017, at 7:53 PM, John McCall  wrote:
>>> 
 On Apr 20, 2017, at 7:31 PM, Douglas Gregor  wrote:
> On Apr 20, 2017, at 3:39 PM, John McCall  wrote:
> 
> On Apr 20, 2017, at 6:35 PM, Xiaodi Wu via swift-evolution 
>  wrote:
>> On Thu, Apr 20, 2017 at 5:03 PM, Douglas Gregor  
>> wrote:
>> 
>> 
 On Apr 20, 2017, at 11:33 AM, Jordan Rose  
 wrote:
 
 
 On Apr 18, 2017, at 20:40, Douglas Gregor via swift-evolution 
  wrote:
 
 This makes the private/fileprivate distinction meaningful for 
 extensions. I think also bans the use of "private" at global scope for 
 non-nominal types or extensions thereof.  A clarifying update to the 
 proposal is in order, so developers can better understand the 
 semantics. 
>>> 
>>> Wait, hang on, then people have to write 'fileprivate' instead of 
>>> 'private' for top-level typealiases (and functions?). 
>> 
>> That seems like the correct behavior; private is about members with 
>> SE-0169. What do you think?
> 
> ...that seems suboptimal, given that the goal has been to make it 
> possible for people to use `private` more and not less frequently. IMO, 
> there's no need for `private typealias` at the global level to be 
> prohibited.
 
 Yeah, I see no reason for this to change the behavior of private 
 extensions to be more restrictive than before.
>>> 
>>> So you’re okay with:
>>> 
>>> private extension X {
>>>   func foo() { }
>>> }
>>> 
>>> being equivalent to
>>> 
>>> extension X {
>>>   fileprivate func foo() { }
>>> }
>>> 
>>> rather than
>>> 
>>> extension X {
>>>   private func foo() { }
>>> }
>>> 
>>> ?
>>> 
>>> That seems unintuitive at best.
>> 
>> Perhaps, but it's existing unintuitive behavior.  Are you suggesting that 
>> SE-0169 rationalizes changing it because (1) it's likely that a private 
>> extension is just meant for the use of other extensions of that type in the 
>> current file and (2) SE-0169 already allows such uses and so justifies the 
>> stricter rule?  That is an interesting theory, but I'm not sure I believe 
>> (1).  
> 
> I’m saying (2), and I suspect (1) is most often the case… but I agree that 
> we’re likely to end up breaking code here.
> 
>> More importantly, though, SE-0169 didn't actually propose changing this 
>> behavior, and it's a very substantial shift in behavior, and we haven't 
>> actually discussed or gathered any community feedback about it, so I'm 
>> really struggling to see why it wouldn't need to be a separate evolution 
>> proposal.  
> 
> I was interpreting SE-0169 to mean this, but you are correct: SE-0169 doesn’t 
> spell out a change here.
> 
>> And that would be difficult because, as a wise man once said to me, the core 
>> team considers the access-control matter closed for Swift 4 and will not be 
>> reviewing any further proposals in this area. :)
> 
> Never put stock in charlatans or compiler writers.
> 
>   - Doug
> 
> 
> ___
> 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-0168: Multi-Line String Literals

2017-04-14 Thread BJ Homer via swift-evolution
I’m not saying that the + operator should automatically add a newline. I’m 
saying that both strings should contain a trailing newline, such that the 
visible result is the same.

By contrast, this would feel really strange:

let a = """
This is line one
This is line two

"""

let b = """
This is line three
This is line four
"""

(a + b) == """
This is line one
This is line two
This is line three
This is line four
"""

On initial intuition, it seems strange that ‘a’ has a blatantly visible blank 
line at the end which seemingly “disappears” when the strings are concatenated. 
If I think about it for a bit, I can understand why that would be the case, but 
I think it’s non-obvious.

-BJ

> On Apr 14, 2017, at 3:49 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> I disagree. I expect the last result to be from `a + "\n" + b`, for the 
> reasons I outlined earlier.
> 
> The concatenation operator + does not introduce implied separators when 
> joining strings. There is no reason to think that it should for multi-line 
> strings specifically.
> On Fri, Apr 14, 2017 at 16:35 BJ Homer via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> Consider these two examples:
>> 
>> let string_1 = """foo"""
>> 
>> 
>> let string_2 = """
>> foo
>> """
>> What’s the intuitive result you’d expect without taking all the long talk 
>> from the list into account?
>> 
>> Personally, I’d say string_1 == string_2 is true.
>> 
> 
> I think it’s reasonable to expect them to be different, actually. I might 
> call these “single-line” and “multi-line” mode strings. The single-line mode 
> is primarily useful for being able to include unescaped double-quotes in the 
> string. If you’re in multi-line mode, though, it’s reasonable to be thinking 
> about things in terms of “lines”, and having a trailing newline there seems 
> reasonable. For example, I think it’s reasonable to expect this:
> 
> let a = """
> This is line one
> This is line two"
> """
> 
> let b = """
> This is line three
> This is line four
> """
> 
> (a + b) == """
> This is line one
> This is line two
> This is line three
> This is line four
> """
> 
> That seems like a reasonable model to work with multi-line strings.
> 
> -BJ
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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-0168: Multi-Line String Literals

2017-04-14 Thread BJ Homer via swift-evolution
> Consider these two examples:
> 
> let string_1 = """foo"""
> 
> 
> let string_2 = """
> foo
> """
> What’s the intuitive result you’d expect without taking all the long talk 
> from the list into account?
> 
> Personally, I’d say string_1 == string_2 is true.
> 

I think it’s reasonable to expect them to be different, actually. I might call 
these “single-line” and “multi-line” mode strings. The single-line mode is 
primarily useful for being able to include unescaped double-quotes in the 
string. If you’re in multi-line mode, though, it’s reasonable to be thinking 
about things in terms of “lines”, and having a trailing newline there seems 
reasonable. For example, I think it’s reasonable to expect this:

let a = """
This is line one
This is line two"
"""

let b = """
This is line three
This is line four
"""

(a + b) == """
This is line one
This is line two
This is line three
This is line four
"""

That seems like a reasonable model to work with multi-line strings.

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


Re: [swift-evolution] SE-0171: Reduce with inout

2017-04-14 Thread BJ Homer via swift-evolution
Ah, that makes sense. I was forgetting that the parameter label was on the 
initial value. 

+1 from me!

-BJ

> On Apr 14, 2017, at 3:07 PM, Guillaume Lessard via swift-evolution 
>  wrote:
> 
> The mutating version would have a parameter label to differentiate it:
> 
> let a = [1, 2, 3, 4, 5]
> 
> let b = a.reduce(into: []) { (result, element) in
>result.append(element * 2)
> }
> 
> --
> GL
> 
> ___
> 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] SE-0171: Reduce with inout

2017-04-14 Thread BJ Homer via swift-evolution
Does inference still work correctly when trailing closure syntax is used, if 
the arguments are not given types?

For example, here’s some code that works in Swift right now:

let a = [1, 2, 3, 4, 5]
let b = a.reduce([]) { (result, element) in
return result + [element * 2]
}

Under the new proposal, this code would also be valid:

let a = [1, 2, 3, 4, 5]

let b = a.reduce([]) { (result, element) in
result.append(element * 2)
}
Note that these both of these closures appear to have the same signature: two 
parameters of inferred type, and an inferred return type. The “inout” and 
return types differ, but neither are specified here. Will the compiler be able 
to correctly infer the types based on the presence or absence of a “return” 
statement in the closure body? If not, it seems like the first example will 
become ambiguous.

-BJ


> On Apr 14, 2017, at 12:37 PM, Ben Cohen via swift-evolution 
> > wrote:
> 
> Hello Swift community,
> 
> The review of “SE-0171: Reduce with inout" begins now and runs through the 
> Friday after next, April 14th. The proposal is available here:
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0171-reduce-with-inout.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/0171-reduce-with-inout.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,
> 
> Ben Cohen
> 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 #2] SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift

2017-04-08 Thread BJ Homer via swift-evolution
I love the idea of a leading and trailing backslash. It makes it much easier to 
read, and handles the "but what if I want to access a property of a KeyPath?" 
case really well.

For example, these two are clearly distinct:

  let x = \Person.mother.age\.valueType

  let y = \Person.mother.age.valueType\

I'm not sure why an 'age' object would have a 'valueType' property, but this 
variant makes it easy to handle. Even in cases where no disambiguation is 
required, having the trailing backslash makes it much easier to read as I'm 
scanning through code.

-BJ

>>> On Apr 5, 2017, at 9:13 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> On Wed, Apr 5, 2017 at 9:21 PM, Ricardo Parada via swift-evolution 
>>>  wrote:
>>> 
>>> On Apr 5, 2017, at 9:41 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
>>> It's worth noting that, if you write `\Person.name.valueType`, this syntax 
>>> is ambiguous—it could mean "make a key path for the `valueType` property on 
>>> `name` property of `Person`", or it could mean "make a key path for the 
>>> `name` property of `Person`, then access the key path's `valueType` 
>>> property". We can solve this by always interpreting it as the former and 
>>> requiring parentheses for the latter—that is, 
>>> `(\Person.name).valueType`—but I thought it was worth calling out 
>>> explicitly.
>> 
>> Good point. 
>> 
>>  I'm thinking about the hypothetical code examples from previous emails:
>> 
>> 
>>let isPuppyQualifier = \Pet.type == .dog && \Pet.age < 12
>>let familyQualifier = (\Family.pets).contains(where: isPuppyQualifier)
>>let familiesWithPuppies = Family.fetch(editingContext, familyQualifier)
> 
> That's an interesting point. While `\` alone seems acceptable, I think it's 
> unfortunate that we'll have `(\...)` and `\(...)` both in the language.
> Can we maybe consider instead:
> 
>   let firstFriendsNameKeyPath = \Person.friends[0].name\
> 
> It is also worth mentioning that, with the sigil, the `keyPath` label may not 
> be so necessary:
> 
>   print(luke[\.friends[0].name])
>   // or, if the suggestion above is accepted
>   print(luke[\.friends[0].name\])
> 
> ___
> 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] [swift-evolution-announce] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

2017-04-07 Thread BJ Homer via swift-evolution
If private is required to be tied to types forever and always, then yes, this 
proposal should be accepted. To do otherwise is to suggest that the use of 
"private" by beginners and the use of same-file extensions by beginners are 
incompatible. The former is silly; "private" is what beginners will naturally 
reach for. The latter is possible, but historically the use of same-file 
extensions has been quite idiomatic. So, I reluctantly agree we should accept 
this proposal.

-BJ

> On Apr 7, 2017, at 10:34 PM, John McCall via swift-evolution 
>  wrote:
> 
> 
>>> On Apr 7, 2017, at 8:12 PM, Jakub Suder via swift-evolution 
>>>  wrote:
>>> 
>>> What is your evaluation of the proposal?
>> 
>> If this is the last option we have to change the status quo, any renaming is 
>> off the table, no further changes after Swift 4, and it's either this or 
>> being stuck with 'fileprivate' until the end of time, then +1 from me. It 
>> will increase the convenience of access control for people like me who see 
>> types and their extensions as parts of the same entity, just spread visually 
>> across neighboring blocks. In almost any other language these two would 
>> indeed be one entity, since most languages don't have any way of dividing 
>> types into pieces this way.
>> 
>> However, IMHO any of these would be a better solution:
> 
> I'd like to respond briefly to this to clarify the Core Team's decisions 
> about what solutions are under consideration, both now and in the future.  By 
> doing this, I don't mean to pressure you towards any particular stance.  The 
> Core Team asked for this to be proposed because we wanted to know how the 
> community felt about it; we are not specifically trying to get it approved, 
> at least as a group.
> 
>> 1) Rename 'private' to something else ('scoped'?) and rename 'fileprivate' 
>> back to 'private'
> 
> The Core Team has rejected making such a major change in the interpretation 
> of 'private'.  'private' will be tied to scopes, now and forever.  The only 
> question is whether extensions of the same type within a file should be 
> considered part of the same scope for the purposes of 'private'.  Swift 4 is 
> the deadline for making that change; if it, too, is rejected, 'private' will 
> be purely lexical forever.
> 
>> 2) Rename 'fileprivate' to something more friendly (I liked the 'local' 
>> suggestion that Vladimir made today)
> 
> The Core Team is willing to consider adding a new keyword to replace 
> 'fileprivate', but not in Swift 4.
> 
> Speaking just for myself, I don't think we'd accept such a change purely for 
> aesthetics; it would have to be because 'fileprivate' seemed inappropriate 
> for some new generalization, e.g. if we added sub-file submodules and wanted 
> 'fileprivate' to allow access only within the submodule.  That is assuming a 
> lot about how a future submodule feature would work, and we aren't going to 
> design that feature specifically with a goal of replacing this keyword, and 
> frankly we don't know when we're going to take that on at all.  I would 
> caution people against assuming that 'fileprivate' will be renamed.
> 
>> 3) Postpone this until we add submodules, but with the assumption that it 
>> will be possible to make some source-breaking changes at that point
> 
> The Core Team is not willing to change the basic design of 'private' in 
> future releases of Swift.  If some feature — perhaps submodules — demands 
> that we define its interaction with 'private', the design of that interaction 
> will have to feel natural and consistent with the at-that-point extant design 
> of 'private'.  For example, it would not be acceptable if, say, adding a 
> submodule declaration to a file suddenly changed the interpretation of 
> 'private'.
> 
> An option (4) that you didn't list but which I should cover for completeness 
> would be to add new keywords in the future with new interpretations.  This is 
> something that the Core Team is willing to consider.  However, speaking just 
> for myself again, I find it unlikely that we would add new access control 
> features just to express increasingly-precise refinements; it would have to 
> be something that felt necessary because of some real inadequacy in the 
> existing access-control levels as applied to some other new feature (e.g. 
> submodules).
> 
> John.
> 
>> The thing I don't like about this proposal (or status quo) - apart from the 
>> fact that it will make people who like the current strict private unhappy - 
>> is that 'private' even right now means kind of two different things:
>> 
>> - for a property or a method defined in a class/struct, it means "available 
>> only inside this type"
>> - for a private global variable/constant/function, or a private type or 
>> extension, it means "available in this file" i.e. the same as 'fileprivate'
>> 
>> So if we're worried that this proposal makes the meaning of 'private' 
>> unclear - it 

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

2017-04-07 Thread BJ Homer via swift-evolution

> On Apr 7, 2017, at 9:23 AM, Matthew Johnson  wrote:
> 
> The most common thing is to have some stored properties that are private and 
> include a handful of fileprivate (or higher) methods that operate on these 
> properties in the type declaration.  All members that don’t need direct 
> access to these properties are placed in extensions specifically to prevent 
> the direct access to stored properties which they don’t need.  This minimizes 
> the lines of code with access to such properties.

Is there a reason this could not be implemented by putting all the sensitive 
stored properties in a separate type from the rest of the code?

-BJ___
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-07 Thread BJ Homer via swift-evolution
> It does not remove the scoped access control, it only relaxes it in 
> extensions to types in the same file.

Many of the use cases for scoped access given during the review of SE-0159 
specifically related to restricting access between extensions in the same file. 
I don't personally use this, but it seems it is definitely used by some 
developers. 

-BJ___
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-07 Thread BJ Homer via swift-evolution
-0.5

SE-0159 was rejected because it was determined that some developers are 
actively using strongly-scoped access control. This proposal removes that 
strong scoping, so I do not see how we can reasonably reject that proposal but 
accept this one.

The entire reason we're having this discussion is that "fileprivate" is such an 
awkward term for something that's so common in the language. I think the main 
thing we need to fix is the naming of that keyword.

I continue to believe that the best solution is to revert "private" to mean 
file scope as in Swift 2, and introduce a new "scoped" keyword for those 
developers who are specifically desiring the scoped functionality. This was 
rejected during the discussion because the migration would be too disruptive, 
but it is only disruptive if the migrator rewrites "private"->"scoped". I 
assert that most developers would not *want* that migration to happen; most 
developers use "private" because they want the default less-than-internal 
access control. The few developers who are using specifically scoped control 
can modify their code manually. Under this model, scoped access control is 
still available for those who need it, and most users can once again use 
"private" in cases where it is the natural default. 

This proposal proposes that "fileprivate" would become a marker to call out 
cases where exceptional across-type access is happening. In practice, I don't 
believe that will happen, simply because there are many existing cases of 
"fileprivate" out there, and this proposal does not suggest migrating them.

I also disagree that it's useful to call out "fileprivate" as an exceptional 
case. It's slightly useful, I'll acknowledge, but it would be *more* useful to 
call out the exceptional cases where scope-only control is being used.

So I disagree with the proposal. But I give it only -0.5 because even with all 
of that, this is a better definition for "private" than the current one.

-BJ

> On Apr 3, 2017, at 12:34 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift Community,
> 
> In rejecting SE-0159, the core team described a potential direction we would 
> like to investigate for “private” access control that admits a limited form 
> of type-based access control within files. The core team is seeking some 
> discussion here and a motivated volunteer to put together a proposal along 
> these lines for review in the Swift 4 time-frame (i.e., very soon). To be 
> clear, the core team it’s sure this is the right direction to go… but it 
> appears promising and we would *love* to be able to settle the access-control 
> issue.
> 
> The design, specifically, is that a “private” member declared within a type 
> “X” or an extension thereof would be accessible from:
> 
>   * An extension of “X” in the same file
>   * The definition of “X”, if it occurs in the same file
>   * A nested type (or extension thereof) of one of the above that occurs 
> in the same file
> 
> This design has a number of apparent benefits:
>   + “private” becomes the right default for “less than whole module” 
> visibility, and aligns well with Swift coding style that divides a type’s 
> definition into a number of extensions.
>   + “fileprivate” remains for existing use cases, but now it’s use it 
> more rare, which has several advantages:
>   + It fits well with the "progressive disclosure” philosophy 
> behind Swift: you can use public/internal/private for a while before 
> encountering and having to learn about “fileprivate”   (note: we thought this 
> was going to be true of SE-0025, but we were clearly wrong)
>   + When “fileprivate” occurs, it means there’s some interesting 
> coupling between different types in the same file. That makes fileprivate a 
> useful alert to the reader rather than, potentially, something that we 
> routinely use and overlook so that we can separate implementations into 
> extensions.
>   + “private” is more closely aligned with other programming languages 
> that use type-based access control, which can help programmers just coming to 
> Swift. When they reach for “private”, they’re likely to get something similar 
> to what they expect—with a little Swift twist due to Swift’s heavy use of 
> extensions.
>   + Loosening the access restrictions on “private” is unlikely to break 
> existing code.
> 
> There are likely some drawbacks:
>   - Developers using patterns that depend on the existing 
> lexically-scoped access control of “private” may find this new interpretation 
> of “private” to be insufficiently strict
>   - Swift’s access control would go from “entirely lexical” to “partly 
> lexical and partly type-based”, which can be viewed as being more complicated
> 
> Thoughts? Volunteer?
> 
>   - Doug
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> 

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

2017-04-04 Thread BJ Homer via swift-evolution

> On Apr 4, 2017, at 1:30 PM, David Hart via swift-evolution 
>  wrote:
> 
> The Core Team has said they will not consider renaming private. End of story.

It sounds like the core team will not consider a code migration that rewrites 
“private” to “scoped”, because it would cause too much code churn. Do we have 
confirmation that they would not consider introducing “scoped” without a 
migration and thus without the attendant code churn? (That is, revert “private” 
back to its Swift 2 meaning, introduce “scoped” in Swift 4, but don’t perform 
any automatic migration from “private” to “scoped”.)

If that kind of change is out of scope, then I agree that this proposal is the 
best remaining alternative. But it’s not the best alternative. It removes the 
strict “scoped private” without a full replacement, and leaves “fileprivate” as 
an awkward name the language. It does leave “private” in a more usable state 
for the common case, which is good. If we have to choose between this and 
nothing, I choose this. But I would still like to hear from the core team 
regarding the possibility of introducing “scoped” without a migration (and thus 
without the code churn they cited as a concern.)

-BJ___
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 BJ Homer via swift-evolution
The proposed relaxation to 'private' is indeed small, and it makes Swift 3's 
"private" a more acceptable "soft default" for restricted access, but it also 
removes the ability of Swift to define a truly scoped access control, which 
some developers have found highly useful.

I would prefer accepting this proposal over doing nothing, as I think "private" 
is broken right now as a soft default, which is unfortunate for a language that 
will be used by so many new programmers. But I think renaming access controls 
without a large migration, as I suggested earlier, would be better. 

-BJ

> On Apr 4, 2017, at 12:45 AM, Goffredo Marocchi via swift-evolution 
>  wrote:
> 
> Considering how small this private rule relaxation is, it seems strange to 
> swat away this proposal...
___
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 BJ Homer via swift-evolution
This type-and-file-based proposal addresses most of the *pragmatic* issues 
people run into when writing Swift, but I agree with other comments that it's a 
difficult mental model.

It sounds like most everyone likes the idea of renaming "private" -> "scoped" 
and "fileprivate" -> "private", but the code churn is considered too large for 
Swift 4. What about the following alternative, which is similar to SE-0159 but 
avoids the code churn:

- Revert the meaning of "private" to the Swift 2 meaning, as in SE-0159.
- Make "fileprivate" an alias for "private", as in SE-0159
- Migrator converts "fileprivate" -> "private", as in SE-0159
- Introduce "scoped", but perform no automatic migration for it.

The discussion around SE-0159 has shown that there are indeed important use 
cases for scoped access control. However, most instances of "private" in the 
wild are probably just due to its position as a "soft default", and don't need 
any migration. Developers who are relying on scoped access control are likely 
to be aware of locations where it is important, and could manually rewrite 
"private" to "scoped" for those sites. (For users who want to perform a full 
migration of "private" -> "scoped", perhaps a manual migration script could be 
provided.)

It's somewhat unfortunate to require manual migration to "scoped" for code that 
cares about scoped access, but I suggest that those use cases are rare and the 
developers are generally aware of such cases. This proposal prefers to limit 
the code churn instead, while getting rid of the "fileprivate" wart on the 
language. Most users would be able to migrate to Swift 4 with only the amount 
of migration already proposed in SE-0159.

-BJ

> On Apr 3, 2017, at 8:34 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift Community,
> 
> In rejecting SE-0159, the core team described a potential direction we would 
> like to investigate for “private” access control that admits a limited form 
> of type-based access control within files. The core team is seeking some 
> discussion here and a motivated volunteer to put together a proposal along 
> these lines for review in the Swift 4 time-frame (i.e., very soon). To be 
> clear, the core team it’s sure this is the right direction to go… but it 
> appears promising and we would *love* to be able to settle the access-control 
> issue.
> 
> The design, specifically, is that a “private” member declared within a type 
> “X” or an extension thereof would be accessible from:
> 
>   * An extension of “X” in the same file
>   * The definition of “X”, if it occurs in the same file
>   * A nested type (or extension thereof) of one of the above that occurs 
> in the same file
> 
> This design has a number of apparent benefits:
>   + “private” becomes the right default for “less than whole module” 
> visibility, and aligns well with Swift coding style that divides a type’s 
> definition into a number of extensions.
>   + “fileprivate” remains for existing use cases, but now it’s use it 
> more rare, which has several advantages:
>   + It fits well with the "progressive disclosure” philosophy 
> behind Swift: you can use public/internal/private for a while before 
> encountering and having to learn about “fileprivate”   (note: we thought this 
> was going to be true of SE-0025, but we were clearly wrong)
>   + When “fileprivate” occurs, it means there’s some interesting 
> coupling between different types in the same file. That makes fileprivate a 
> useful alert to the reader rather than, potentially, something that we 
> routinely use and overlook so that we can separate implementations into 
> extensions.
>   + “private” is more closely aligned with other programming languages 
> that use type-based access control, which can help programmers just coming to 
> Swift. When they reach for “private”, they’re likely to get something similar 
> to what they expect—with a little Swift twist due to Swift’s heavy use of 
> extensions.
>   + Loosening the access restrictions on “private” is unlikely to break 
> existing code.
> 
> There are likely some drawbacks:
>   - Developers using patterns that depend on the existing 
> lexically-scoped access control of “private” may find this new interpretation 
> of “private” to be insufficiently strict
>   - Swift’s access control would go from “entirely lexical” to “partly 
> lexical and partly type-based”, which can be viewed as being more complicated
> 
> Thoughts? Volunteer?
> 
>   - Doug
> ___
> 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 BJ Homer via swift-evolution
'forAll' is definitely confusing; it sounds like iteration; I would not expect 
that the closure would be required to return a Bool. The implementation would 
likely bail out as soon as a single item failed the test; there is no guarantee 
that each item would be visited, so iteration is an incorrect mental model.

In Python, this is just called 'all()'. (There is a corresponding 'any()'.) We 
could follow the example of 'filter(_ isIncluded:)', which has a in internal 
parameter name for documentation, but takes no parameter at the call site; this 
might look like 'all(_ predicate:)'. Or we could follow the example of 
'drop(while:)' and do 'all(test:)'. (And with trailing closure syntax, this 
would simply become 'all' (e.g.  'let readyToGo = collection.all { $0.isReady 
}'.

If a more explicit base name is desired, I suggest 'allPass(test:)'.

-BJ

> On Apr 2, 2017, at 3:17 AM, Richard Wei via swift-evolution 
>  wrote:
> 
> `withoutException` sounds confusing to me. And it’ll potentially make a Swift 
> newcomer think it has something to do with runtime exceptions.
> 
> IMO `forAll(_:)` is the best name. It looks logically, quantificationally 
> clear. With regard to the possible confusion w/ `forEach`, the “each" in 
> `forEach` conveys the sense of iteration, while the “all” in `forAll` conveys 
> both iteration and conjunction.
> 
> -Richard
> 
>> On Apr 2, 2017, at 00:05, Robert Bennett via swift-evolution 
>>  wrote:
>> 
>> It figures, the hardest thing to pick is the name of this function…
>> 
>> I like forAll the best so far, but I worry that it sounds too much like 
>> forEach and would be confusing.
>> 
>> What does everyone think of withoutException? nums.withoutException(isEven) 
>> and nums.withoutException { isEven($0) } make their purpose clear, and even 
>> make clear what happens for an empty Collection.
>> 
>> Other options that come to mind that I am less enthusiastic about:
>> 
>> nums.every(satisfies: isEven) / nums.every { isEven($0) }
>> nums.entirely(isEven) / nums.entirely { isEven($0) }
>> ___
>> 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] Smart KeyPaths

2017-03-31 Thread BJ Homer via swift-evolution

> Is it always in the form of $R?

No. Prefixing a variable with a '$' allows you to create a long-lasting 
variable in lldb. By default, every 'expr' command runs in its own scope, which 
means identifiers defined in one command are not visible from another. Example:

(LLDB) expr let x = 1 + 2
$R0 = 3
(LLDB) print x + 3
Error: Undefined identifier 'x'
(LLDB) expr let $y = 3 + 4
$R1 = 7
(LLDB) print $y + 5
$R2 = 12

Typed on my phone, so the LLDB output is not exact, but you see the point: you 
can prefix an identifier with '$' to make it persist beyond the scope of that 
command. LLDB automatically creates numbered identifiers when running commands, 
but you can also create your own. And you could also have expressions like 
'print $person.name', so looking for a '.' doesn't help. 

-BJ
___
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-22 Thread BJ Homer via swift-evolution
What is your evaluation of the proposal?
I agree with the proposal. While I acknowledge that a lexically-scoped access 
modifier can be useful, giving it the name “private” in Swift is unfortunate. 
Much of the existing Swift training material suggests a common pattern of 
adding protocol conformances via extensions. For example, this kind of code is 
very common:

class ToyViewController: UIViewController {
  private var toysToDisplay: [Toy]
}

extension ToyViewController: UICollectionViewDataSource {
  // Implement the data source protocol here
}

However, this pattern is broken; toysToDisplay cannot be labeled private 
because then it cannot be accessed within the extension. It needs to be 
fileprivate instead. But this adds a barrier to learning; while private is a 
common programming term, fileprivate is not. Most users will try private first. 
I believe Swift should intentionally be biased toward ease of use, and the use 
of private to signify scope-level access goes against that principle.

There was an argument earlier in the thread that extensions are intended for 
augmenting a type from the outside. In my experience, it is equally common to 
have a type and extensions on that type in the same file. This has been 
demonstrated in WWDC sessions, in training documents, and is common practice 
among many of the Swift developers I have worked with.

In Swift 3, there is tension between adding protocol conformances in extensions 
and having private as the soft default for limiting access. I agree that a 
lexically-scoped access modifier can be useful, but I think it should be 
spelled scoped. “private” should revert to its Swift 2 meaning, which is more 
compatible with the extension- and protocol-oriented nature of Swift. It would 
be nice if we could make both changes at once, but if that is not possible, it 
would be better to make the potentially source-breaking change in the Swift 4 
timeline, as the bar for source-breaking changes will only increase with each 
release. "Scoped" access can be added back after Swift 4, if it cannot be part 
of this release.


Is the problem being addressed significant enough to warrant a change to Swift?
Yes. The requirement to use fileprivate when adding extensions within the same 
file makes Swift more difficult to learn.
Does this proposal fit well with the feel and direction of Swift?
Yes. Swift is intended to be a language that is both easy to learn and easy to 
use. The common use of private makes the language more difficult to learn. 
“scoped” access should be a more advanced feature.
If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?
Swift is intentionally different here, and I think it’s correct for Swift to be 
different.
How much effort did you put into your review? A glance, a quick reading, or an 
in-depth study?
I followed the SE-0025 conversation, this conversation, and have used both 
Swift 2 and Swift 3 extensively. Even though I know that I’m usually going to 
need fileprivate, it’s such an awkward term that I usually end up writing 
private anyway, and then regretting it. Ideally, we would continue supporting 
both scoped and file-level access control, by renaming both of them. But 
because of the increasing bar for source compatibility, I think it’s better to 
make this change now, and reintroduce scoped access as soon as possible.

-BJ



> On Mar 20, 2017, at 5:54 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0159 "Fix Private Access Levels" begins now and runs through 
> March 27, 2017. The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.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/0159-fix-private-access-levels.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 

Re: [swift-evolution] Smart KeyPaths

2017-03-17 Thread BJ Homer via swift-evolution
So then this would be disambiguated like this?

let staticValue = Foo.bar // Defaults to accessing the static value, when there 
is ambiguity

let value:   Bar   = Foo.bar
let keyPath: WritableKeyPath = Foo.bar

It’s a little unfortunately to have to spell out WritableKeyPath 
there, but as long as there’s some way to do it, I don’t think it’s a problem. 
This is likely a rare edge case.

-BJ Homer

> On Mar 17, 2017, at 3:56 PM, Joe Groff  wrote:
> 
>> 
>> On Mar 17, 2017, at 2:53 PM, Michael LeHew > > wrote:
>> 
>> 
>>> On Mar 17, 2017, at 2:21 PM, BJ Homer >> > wrote:
>>> 
>>> This looks great!
>>> 
>>> What happens in the case when there is a static property by the same name 
>>> as an instance property? e.g.
>>> 
>>> struct Foo {
>>> static var bar: Bar
>>> var bar: Bar
>>> }
>>> 
>>> Foo.bar // What is this?
>>> 
>>> Is it still possible to reference both the static property and a KeyPath to 
>>> the instance method? 
>> 
>> This is essentially the same question that I arrived at in my reply to 
>> Vladimir.  I think Joe might be best able to answer here.
> 
> We already encounter this situation with static vs instance methods, since 
> `Foo.bar` can refer to either a static method `bar` or an unbound instance 
> method `bar`. We use type context to disambiguate, favoring the static member 
> if context doesn't help:
> 
> struct X {
>   static func foo() {}
>   func foo() {}
> }
> 
> let foo1 = X.foo // Defaults to static member
> let foo2: () -> () = X.foo // Picks static member by type context
> let foo3: (X) -> () -> () = X.foo // Picks instance member by type context
> 
> -Joe

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


Re: [swift-evolution] Smart KeyPaths

2017-03-17 Thread BJ Homer via swift-evolution
This looks great!

What happens in the case when there is a static property by the same name as an 
instance property? e.g.

struct Foo {
static var bar: Bar
var bar: Bar
}

Foo.bar // What is this?

Is it still possible to reference both the static property and a KeyPath to the 
instance method? 

-BJ

> On Mar 17, 2017, at 11:04 AM, Michael LeHew via swift-evolution 
>  wrote:
> 
> Hi friendly swift-evolution folks,
> 
> The Foundation and Swift team  would like for you to consider the following 
> proposal:
> 
> Many thanks,
> -Michael
> 
> Smart KeyPaths: Better Key-Value Coding for Swift
> Proposal: SE-
> Authors: David Smith , Michael LeHew 
> , Joe Groff 
> Review Manager: TBD
> Status: Awaiting Review
> Associated PRs:
> #644 
> Introduction
> We propose a family of concrete Key Path types that represent uninvoked 
> references to properties that can be composed to form paths through many 
> values and directly get/set their underlying values.
> 
> Motivation
> We Can Do Better than String
> 
> On Darwin platforms Swift's existing #keyPath() syntax provides a convenient 
> way to safely refer to properties. Unfortunately, once validated, the 
> expression becomes a String which has a number of important limitations:
> 
> Loss of type information (requiring awkward Any APIs)
> Unnecessarily slow to parse
> Only applicable to NSObjects
> Limited to Darwin platforms
> Use/Mention Distinctions
> 
> While methods can be referred to without invoking them (let x = foo.bar 
> instead of  let x = foo.bar()), this is not currently possible for properties 
> and subscripts.
> 
> Making indirect references to a properties' concrete types also lets us 
> expose metadata about the property, and in the future additional behaviors.
> 
> More Expressive KeyPaths
> 
> We would also like to support being able to use Key Paths to access into 
> collections, which is not currently possible.
> 
> Proposed solution
> We propose introducing a new expression akin to Type.method, but for 
> properties and subscripts. These property reference expressions produce 
> KeyPath objects, rather than Strings. KeyPaths are a family of generic 
> classes (structs and protocols here would be ideal, but requires generalized 
> existentials) which encapsulate a property reference or chain of property 
> references, including the type, mutability, property name(s), and ability to 
> set/get values.
> 
> Here's a sample of it in use:
> 
> Swift
> struct Person {
> var name: String
> var friends: [Person]
> var bestFriend: Person?
> }
> 
> var han = Person(name: "Han Solo", friends: [])
> var luke = Person(name: "Luke Skywalker", friends: [han])
> 
> let firstFriendsNameKeyPath = Person.friends[0].name
> 
> let firstFriend = luke[path] // han
> 
> // or equivalently, with type inferred from context
> let firstFriendName = luke[.friends[0].name]
> 
> // rename Luke's first friend
> luke[firstFriendsNameKeyPath] = "A Disreputable Smuggler"
> 
> let bestFriendsName = luke[.bestFriend]?.name  // nil, if he is the last jedi
> Detailed design
> Core KeyPath Types
> 
> KeyPaths are a hierarchy of progressively more specific classes, based on 
> whether we have prior knowledge of the path through the object graph we wish 
> to traverse. 
> 
> Unknown Path / Unknown Root Type
> 
> AnyKeyPath is fully type-erased, referring to 'any route' through an 
> object/value graph for 'any root'. Because of type-erasure many operations 
> can fail at runtime and are thus nillable. 
> 
> Swift
> class AnyKeyPath: CustomDebugStringConvertible, Hashable {
> // MARK - Composition
> // Returns nil if path.rootType != self.valueType
> func appending(path: AnyKeyPath) -> AnyKeyPath?
> 
> // MARK - Runtime Information
> class var rootType: Any.Type
> class var valueType: Any.Type
> 
> static func == (lhs: AnyKeyPath, rhs: AnyKeyPath) -> Bool
> var hashValue: Int
> }
> Unknown Path / Known Root Type
> 
> If we know a little more type information (what kind of thing the key path is 
> relative to), then we can use PartialKeyPath , which refers to an 'any 
> route' from a known root:
> 
> Swift
> class PartialKeyPath: AnyKeyPath {
> // MARK - Composition
> // Returns nil if Value != self.valueType
> func appending(path: AnyKeyPath) -> PartialKeyPath?
> func appending(path: KeyPath) 
> -> KeyPath?
> func appending(path: ReferenceKeyPath AppendedValue>) -> ReferenceKeyPath?
> }
> Known Path / Known Root Type
> 
> When we know both what the path is relative to and what it refers to, we can 
> use KeyPath. Thanks to the knowledge of the Root and Value types, all of the 
> failable operations lose their 

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

2017-03-03 Thread BJ Homer via swift-evolution
I agree that “scope(set: file)” reads better. It does make it a little strange 
that “scope(set)" is also valid, though; it’s ambiguous whether it takes 
labeled or unlabeled arguments. Under this proposal, all of these are valid:

scope var   == scope(get, lexical)
scope(set) var  == scope(set, lexical)
private(set) var== scope(set, file)
internal(set) var   == scope(set, submodule)
public(set) var == scope(set, everywhere)

For beginner users, the use of “scope” as both an access modifier and a 
capability modifier seems a bit confusing; we’re “complecting” access control 
and capability control. Perhaps we should avoid the concept of “default 
arguments” altogether by separating the “scope” access control keyword from the 
concept of capability control. What about something like this?

scoped var  == access(get: lexical)
scoped(set) var == access(set: lexical)
private(set) var== access(set: file)
internal(set) var   == access(set: submodule)
public(set) var == access(set: everywhere)

Under this proposal, “scoped” is just another alias, similar to “private", 
“internal", and “public”. It does not have a privileged position, and it’s 
written as an adjective just like the others. The downside here is that we’re 
introducing two new keywords instead of one, but it means that we don’t need to 
mentally insert any default arguments. (The name of “access” is a placeholder, 
subject to bikeshedding.)

-BJ



> On Mar 3, 2017, at 4:23 AM, Daniel Leping via swift-evolution 
>  wrote:
> 
> General impression is positive in case shortcuts (private, bulblic) still 
> remain for the most common use cases.
> 
> On Thu, 2 Mar 2017 at 21:58 Matthew Johnson via swift-evolution 
> > wrote:
> I’ve been continuing to think about how to provide clear and consistent 
> semantics for access control in Swift.  This draft represents what I think is 
> the best way to accomplish that.  It eliminates the current inconsistencies 
> and establishes a principled basis for the features we have today as well as 
> the enhancements we may need in the future.  It does this with minimal 
> breaking changes.
> 
> The draft is included below and can also be found here: 
> https://github.com/anandabits/swift-evolution/blob/scope-bounded-capabilities/proposals/-scope-bounded-capabilities.md
>  
> .
> 
> I’m looking forward to everyone’s feedback.
> 
> Matthew
> 
> 
> A Consistent Foundation For Access Control: Scope-Bounded Capabilities
> 
> Proposal: SE- 
> 
> Authors: Matthew Johnson 
> Review Manager: TBD
> Status: Awaiting review
>  
> Introduction
> 
> This proposal introduces a consistent foundation for all access control in 
> Swift: scope-bounded capabilities. The existing access control features are 
> generalized with a single mechanism that unifies their semantics. This 
> unified mechanism eliminates the inessential complexity and inconsistency of 
> the current system while expanding its utility. 
> 
> Swift-evolution thread: Discussion thread topic for that proposal 
> 
>  
> Motivation
> 
> The new access control features in Swift 3 have proven to be extremely 
> controversial. The most common refrain is that we need a more simple system. 
> In order to accomplish this we need to do more than tweak the system we 
> already have. We need to revisit the foundation of the system itself.
> 
>  
> Simple
>  Made Easy
> 
> Rich Hickey gave a fantastic talk called [Simple Made 
> Easy])(https://www.infoq.com/presentations/Simple-Made-Easy 
> ). In this talk Rich 
> explores the etymology and relationship of the words "simple", "complex", and 
> "easy". The meanings he explores are:
> 
> Complex: entangled, intertwined, interleaved, braided together
> Simple: one strand, single focus, disentangled
> Easy: familiar, nearby, readily at hand
> The central point Rich makes in this talk is that when a design entangles two 
> orthogonal concepts complexity is the result. He coins the term "complect" to 
> refer 

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

2017-02-21 Thread BJ Homer via swift-evolution
This sentence in the Motivation sentence is confusing:

Before offering solutions, lets discuss how and why it can be viewed as 
actiely harmful, the new requirement for syntax/API changes.

I would suggest rewording it as follows:
  
Before offering solution, let’s discuss how and why it can be viewed as 
actively harmful (which is the new requirement for syntax/API changes.)

My initial parsing of this sentence was “let’s discuss how the new requirement 
for syntax/API changes can be viewed as actively harmful”, which is not the 
intended meaning.

-BJ

> On Feb 20, 2017, at 11:58 PM, David Hart via swift-evolution 
>  wrote:
> 
> Hello list,
> 
> Matthew Johnson and I have been putting our proposals together towards a 
> joint “let’s fix private access levels” proposal. As the community seems 
> quite divided on the issue, we offer two solutions in our proposal to let the 
> community debate and to let the core team make the final decision.
> 
> I’d like to concentrate this round of feedback on the quality of the 
> proposal, and not on the merits of Solution 1 or 2. thoughts?
> 
> https://github.com/hartbit/swift-evolution/blob/fix-private-access-levels/proposals/-fix-private-access-levels.md
>  
> 
> 
> David.
> 
> Fix Private Access Levels
> 
> Proposal: SE- 
> 
> Authors: David Hart , Matthew Johnson 
> 
> Review Manager: TBD
> Status: TBD
>  
> Introduction
> 
> This proposal presents the problems the came with the the access level 
> modifications in SE-0025 
> 
>  and presents two community driven solutions to fix them. As a consensus will 
> not easily emerge, this proposal will allow a last round of voting and let 
> the core team decide. Once that is done, this proposal will be ammended to 
> describe the chosen solution.
> 
>  
> Motivation
> 
> Since the release of Swift 3, the access level change of SE-0025 was met with 
> dissatisfaction by a substantial proportion of the general Swift community. 
> Before offering solutions, lets discuss how and why it can be viewed as 
> actiely harmful, the new requirement for syntax/API changes.
> 
>  
> Criticisms
>  of SE-0025
> 
> There are two primary criticism that have been offered.
> 
> The first is that private is a "soft default" access modifier for restricting 
> access within a file. Scoped access is not a good behavior for a "soft 
> default" because it is extremely common to use several extensions within a 
> file. A "soft default" (and therefore private) should work well with this 
> idiom. It is fair to say that changing the behavior of private such that it 
> does not work well with extensions meets the criteria of actively harmful in 
> the sense that it subtly encourages overuse of scoped access control and 
> discourages the more reasonable default by giving it the awkward name 
> fileprivate.
> 
> The second is that Swift's system of access control is too complex. Many 
> people feel like restricting access control to scopes less than a file is of 
> dubious value and therefore wish to simplify Swift's access control story by 
> removing scoped access. However, there are many others who like the ability 
> to have the compiler verify tighter access levels and believe it helps make 
> it easier to reason about code which is protecting invariants.
> 
>  
> Detailed
>  design
> 
> Both authors agree that the private keyword should be reverted back to its 
> Swift 2 file-based meaning, resolving the first criticism. But the authors 
> disagree on what should be done about the scoped access level and the 
> following solutions represent the two main opinions in the community:
> 
>  
> Solution
>  1: Remove the scoped access level
> 
> Compared to a file-based access level, the scoped-based access level adds 
> meaningful information by hiding implementation details which do not concern 
> other types or extensions in the same file. But is that distinction between 
> private and fileprivate actively used by the larger community of Swift 
> developers? And if it were used pervasively, would it be worth the cognitive 
> load and complexity of keeping two very similar access levels 

[swift-evolution] [pitch] Eliminate the "T1 -> T2" syntax, require "(T1) -> T2"

2016-04-21 Thread BJ Homer via swift-evolution
How would this proposal affect curried functions? Would this:

   func foo(int: Int) -> Int -> String -> String

become this?

   func foo(int: Int) -> (((Int) -> String) -> String)

As I understand, that transformation is an accurate representation of the 
actual return type of “foo”, but it’s certainly going to raise some complaints 
among the functional Swift community if required.

-BJ




> We currently accept function type syntax without parentheses, like:
> 
> Int ->Float
> String ->()
> 
> etc. The original rationale aligned with the fact that we wanted to treat all 
> functions as taking a single parameter (which was often of tuple type) and 
> producing a tuple value (which was sometimes a tuple, in the case of void and 
> multiple return values). However, we’ve long since moved on from that early 
> design point: there are a number of things that you can only do in a 
> parameter list now (varargs, default args, etc), implicit tuple splat has 
> been removed, and the compiler has long ago stopped modeling function 
> parameters this way. Beyond that, it eliminates one potential style war.
> 
> Given all this, I think it makes sense to go for syntactic uniformity between 
> parameter list and function types, and just require parenthesis on the 
> argument list. The types above can be trivially written as:
> 
> (Int) ->Float
> (String) ->()
> 
> Thoughts?
> 
> -Chris
> 
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [pitch] Eliminate the "T1 -> T2" syntax, require "(T1) -> T2"

2016-04-20 Thread BJ Homer via swift-evolution
How would this proposal affect curried functions? Would this:

  func foo(int: Int) -> Int -> String -> String

become this?

  func foo(int: Int) -> (((Int) -> String) -> String)

As I understand, that transformation is an accurate representation of the 
actual return type of “foo”, but it’s certainly going to raise some complaints 
among the functional Swift community if required.

-BJ




> We currently accept function type syntax without parentheses, like:
> 
> Int ->Float
> String ->()
> 
> etc. The original rationale aligned with the fact that we wanted to treat all 
> functions as taking a single parameter (which was often of tuple type) and 
> producing a tuple value (which was sometimes a tuple, in the case of void and 
> multiple return values). However, we’ve long since moved on from that early 
> design point: there are a number of things that you can only do in a 
> parameter list now (varargs, default args, etc), implicit tuple splat has 
> been removed, and the compiler has long ago stopped modeling function 
> parameters this way. Beyond that, it eliminates one potential style war.
> 
> Given all this, I think it makes sense to go for syntactic uniformity between 
> parameter list and function types, and just require parenthesis on the 
> argument list. The types above can be trivially written as:
> 
> (Int) ->Float
> (String) ->()
> 
> Thoughts?
> 
> -Chris
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution