Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
Just realized that even inout functions don’t let you do member(object) = 
value. So you’re right, the write access does make keypaths more like 
subscripts. But when restricted to read-only access, they are identical to 
(non-inout) functions and so it does seem natural to be able to use them as 
such for the purpose of map and similar functions.

You’ve convinced me that the sigil method is probably preferable... Since write 
access does make keypaths more like subscripts, the proper way to convert 
keypaths to functions is probably an explicit piece of punctuation.

> On Jul 11, 2017, at 9:23 PM, Robert Bennett via swift-evolution 
>  wrote:
> 
> Sure, but you could just as easily call a keypath “a thing that gives you 
> read+write access to one of an object’s members”. Sounds like an inout 
> function to me. The difference being that in general an inout function *can* 
> do a lot more than just give access to a single member of a base object. But 
> a keypath is still just a (constrained) inout function.
> 
>> On Jul 11, 2017, at 9:14 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>>> on Tue Jul 11 2017, Robert Bennett  wrote:
>>> 
>>> Er, yes, I now realize I diverged into two different keypaths-as-functions 
>>> ideas there.
>>> 
>>> I think that the best implementation of deferred access is keypaths as
>>> callable first-class objects, like you (Karl) said. — although I
>>> wonder whether callability should be restricted to KeyPath, or
>>> instead, if the notion of a callable type should gain first-class
>>> language support.
>>> 
>>> If not possible, then a conversion sigil to make a KeyPath into a function. 
>>> After that, giving
>>> KeyPath a function `apply` is probably next best.
>>> 
>>> I like the subscript idea the least because: I don’t like the look of
>>> the syntax, keypaths feel more function-y than subscript-y, 
>>> and it diminishes the flexibility of keypaths (as this thread has
>>> revealed).
>> 
>> Because they're parameterized by a base object and a key, and (in
>> general) they're writable, they're semantically very much like
>> subscripts.
>> 
 On Jul 11, 2017, at 7:56 PM, Karl Wagner  wrote:
 
 
> On 12. Jul 2017, at 01:20, Robert Bennett
>  > wrote:
> 
> Well, if they really are first-class deferred method calls or
> member accesses, then do seem pretty function-y after all. Then
> again, if they were meant to be functions, it seems like their
> design would reflect that – instead of being used like subscripts,
> they would be called like functions, and since new syntax had to be
> created either way, the fact that they *weren't* just made into
> callable objects seems to indicate that that was not the intent,
> although I’d have to go back and read the discussion to see exactly
> what was discussed.
 
 I agree, and I suspect I’m not alone in disliking the subscript syntax.
 
> 
> That said, I agree with Benjamin that having an `apply` method for
> KeyPath seems like the right way to make (or have made) keypaths
> work. keypath.apply(to: instance) (or keypath.evaluate(on:), or
> some other name that gets the idea across) reads just as nice as
> instance[keyPath: keypath] and has the added benefit of allowing
> collection.map(keypath.apply) at no cost. But it’s probably too
> late to even bother having a discussion about this, right?
 
 I don’t think so. That’s why we have a beta. Real-world experience
 has shown that we would often like to erase a KeyPath and use it as
 if it were a closure. Maybe we want to pass a KeyPath as a parameter
 to a function such as “map", which accepts a closure, or we want to
 set a variable with a closure-type using a KeyPath. Those functions
 and stored properties don’t care about the special properties of
 KeyPaths (e.g. that they are Codable) - they only care that they are
 executable on a base object to produce a result. You can wrap the
 key-paths inside closures, but it’s cumbersome and some developers
 are asking for a shorthand to perform that erasure.
 
 Personally, I would be in favour of making the erasure implicit and 
 allowing KeyPaths to be invoked using function-syntax:
 
 // Invocation using function-syntax:
 
 let _: Value = someClosure(parameter)
 let _: Value = someKeypath(parameter)
 
 let _: Value = { $0.something.anotherThing }(parameter)
 let _: Value = (\MyObj.something.anotherThing)(parameter)
 
 // Implicit erasure to closure-type:
 
 class PrettyTableCell {
   let titleFormatter: (T) -> String
 }
 let cell= PrettyTableCell()
 cell.titleFormatter = \MyObj.something.name
 
 let stuff = 

Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
Sure, but you could just as easily call a keypath “a thing that gives you 
read+write access to one of an object’s members”. Sounds like an inout function 
to me. The difference being that in general an inout function *can* do a lot 
more than just give access to a single member of a base object. But a keypath 
is still just a (constrained) inout function.

> On Jul 11, 2017, at 9:14 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
>> on Tue Jul 11 2017, Robert Bennett  wrote:
>> 
>> Er, yes, I now realize I diverged into two different keypaths-as-functions 
>> ideas there.
>> 
>> I think that the best implementation of deferred access is keypaths as
>> callable first-class objects, like you (Karl) said. — although I
>> wonder whether callability should be restricted to KeyPath, or
>> instead, if the notion of a callable type should gain first-class
>> language support.
>> 
>> If not possible, then a conversion sigil to make a KeyPath into a function. 
>> After that, giving
>> KeyPath a function `apply` is probably next best.
>> 
>> I like the subscript idea the least because: I don’t like the look of
>> the syntax, keypaths feel more function-y than subscript-y, 
>> and it diminishes the flexibility of keypaths (as this thread has
>> revealed).
> 
> Because they're parameterized by a base object and a key, and (in
> general) they're writable, they're semantically very much like
> subscripts.
> 
>>> On Jul 11, 2017, at 7:56 PM, Karl Wagner  wrote:
>>> 
>>> 
 On 12. Jul 2017, at 01:20, Robert Bennett
 > wrote:
 
 Well, if they really are first-class deferred method calls or
 member accesses, then do seem pretty function-y after all. Then
 again, if they were meant to be functions, it seems like their
 design would reflect that – instead of being used like subscripts,
 they would be called like functions, and since new syntax had to be
 created either way, the fact that they *weren't* just made into
 callable objects seems to indicate that that was not the intent,
 although I’d have to go back and read the discussion to see exactly
 what was discussed.
>>> 
>>> I agree, and I suspect I’m not alone in disliking the subscript syntax.
>>> 
 
 That said, I agree with Benjamin that having an `apply` method for
 KeyPath seems like the right way to make (or have made) keypaths
 work. keypath.apply(to: instance) (or keypath.evaluate(on:), or
 some other name that gets the idea across) reads just as nice as
 instance[keyPath: keypath] and has the added benefit of allowing
 collection.map(keypath.apply) at no cost. But it’s probably too
 late to even bother having a discussion about this, right?
>>> 
>>> I don’t think so. That’s why we have a beta. Real-world experience
>>> has shown that we would often like to erase a KeyPath and use it as
>>> if it were a closure. Maybe we want to pass a KeyPath as a parameter
>>> to a function such as “map", which accepts a closure, or we want to
>>> set a variable with a closure-type using a KeyPath. Those functions
>>> and stored properties don’t care about the special properties of
>>> KeyPaths (e.g. that they are Codable) - they only care that they are
>>> executable on a base object to produce a result. You can wrap the
>>> key-paths inside closures, but it’s cumbersome and some developers
>>> are asking for a shorthand to perform that erasure.
>>> 
>>> Personally, I would be in favour of making the erasure implicit and 
>>> allowing KeyPaths to be invoked using function-syntax:
>>> 
>>> // Invocation using function-syntax:
>>> 
>>> let _: Value = someClosure(parameter)
>>> let _: Value = someKeypath(parameter)
>>> 
>>> let _: Value = { $0.something.anotherThing }(parameter)
>>> let _: Value = (\MyObj.something.anotherThing)(parameter)
>>> 
>>> // Implicit erasure to closure-type:
>>> 
>>> class PrettyTableCell {
>>>let titleFormatter: (T) -> String
>>> }
>>> let cell= PrettyTableCell()
>>> cell.titleFormatter = \MyObj.something.name
>>> 
>>> let stuff = myObjects.map(\.something.anotherThing)
>>> 
>>> - Karl
>>> 
 
> On Jul 11, 2017, at 6:27 PM, Karl Wagner
>  > wrote:
> 
> 
>> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution
>> > >
>> wrote:
>> 
>> In general, I like the idea of making ordinary types callable
>> (although curried functions already accomplish this to some
>> extent), but I hesitate to bring this capability to keypaths
>> because, well, they don’t really feel like functions; I think the
>> point of them is that they work like subscripts, not
>> functions. After all, before keypaths were added, there was
>> already an easy to make a 

Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Dave Abrahams via swift-evolution

on Tue Jul 11 2017, Robert Bennett  wrote:

> Er, yes, I now realize I diverged into two different keypaths-as-functions 
> ideas there.
>
> I think that the best implementation of deferred access is keypaths as
> callable first-class objects, like you (Karl) said. — although I
> wonder whether callability should be restricted to KeyPath, or
> instead, if the notion of a callable type should gain first-class
> language support.
>
> If not possible, then a conversion sigil to make a KeyPath into a function. 
> After that, giving
> KeyPath a function `apply` is probably next best.
>
> I like the subscript idea the least because: I don’t like the look of
> the syntax, keypaths feel more function-y than subscript-y, 
> and it diminishes the flexibility of keypaths (as this thread has
> revealed).

Because they're parameterized by a base object and a key, and (in
general) they're writable, they're semantically very much like
subscripts.

>> On Jul 11, 2017, at 7:56 PM, Karl Wagner  wrote:
>> 
>> 
>>> On 12. Jul 2017, at 01:20, Robert Bennett
>>> >> > wrote:
>>> 
>>> Well, if they really are first-class deferred method calls or
>>> member accesses, then do seem pretty function-y after all. Then
>>> again, if they were meant to be functions, it seems like their
>>> design would reflect that – instead of being used like subscripts,
>>> they would be called like functions, and since new syntax had to be
>>> created either way, the fact that they *weren't* just made into
>>> callable objects seems to indicate that that was not the intent,
>>> although I’d have to go back and read the discussion to see exactly
>>> what was discussed.
>> 
>> I agree, and I suspect I’m not alone in disliking the subscript syntax.
>> 
>>> 
>>> That said, I agree with Benjamin that having an `apply` method for
>>> KeyPath seems like the right way to make (or have made) keypaths
>>> work. keypath.apply(to: instance) (or keypath.evaluate(on:), or
>>> some other name that gets the idea across) reads just as nice as
>>> instance[keyPath: keypath] and has the added benefit of allowing
>>> collection.map(keypath.apply) at no cost. But it’s probably too
>>> late to even bother having a discussion about this, right?
>> 
>> I don’t think so. That’s why we have a beta. Real-world experience
>> has shown that we would often like to erase a KeyPath and use it as
>> if it were a closure. Maybe we want to pass a KeyPath as a parameter
>> to a function such as “map", which accepts a closure, or we want to
>> set a variable with a closure-type using a KeyPath. Those functions
>> and stored properties don’t care about the special properties of
>> KeyPaths (e.g. that they are Codable) - they only care that they are
>> executable on a base object to produce a result. You can wrap the
>> key-paths inside closures, but it’s cumbersome and some developers
>> are asking for a shorthand to perform that erasure.
>> 
>> Personally, I would be in favour of making the erasure implicit and allowing 
>> KeyPaths to be invoked using function-syntax:
>> 
>> // Invocation using function-syntax:
>> 
>> let _: Value = someClosure(parameter)
>> let _: Value = someKeypath(parameter)
>> 
>> let _: Value = { $0.something.anotherThing }(parameter)
>> let _: Value = (\MyObj.something.anotherThing)(parameter)
>> 
>> // Implicit erasure to closure-type:
>> 
>> class PrettyTableCell {
>> let titleFormatter: (T) -> String
>> }
>> let cell= PrettyTableCell()
>> cell.titleFormatter = \MyObj.something.name
>> 
>> let stuff = myObjects.map(\.something.anotherThing)
>> 
>> - Karl
>> 
>>> 
 On Jul 11, 2017, at 6:27 PM, Karl Wagner
 > wrote:
 
 
> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution
>  >
> wrote:
> 
> In general, I like the idea of making ordinary types callable
> (although curried functions already accomplish this to some
> extent), but I hesitate to bring this capability to keypaths
> because, well, they don’t really feel like functions; I think the
> point of them is that they work like subscripts, not
> functions. After all, before keypaths were added, there was
> already an easy to make a function that does what a keypath does
> (which makes me wonder whether keypaths were necessary in the
> first place, but that ship has sailed). The only reason to add
> callable support to keypaths is for use in map, which I don’t
> think justifies making them callable.
> 
> Also, since I brought this up, I’d like to be proved wrong about keypaths 
> – what use do they have that isn’t accomplished by the equivalent closure?
 
 I can’t find a formal definition of a “keypath”, so let me explain how I 
 think of them:
 
 Conceptually, I 

Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
Er, yes, I now realize I diverged into two different keypaths-as-functions 
ideas there.

I think that the best implementation of deferred access is keypaths as callable 
first-class objects, like you (Karl) said. — although I wonder whether 
callability should be restricted to KeyPath, or instead, if the notion of a 
callable type should gain first-class language support.

If not possible, then a conversion sigil to make a KeyPath into a function. 
After that, giving KeyPath a function `apply` is probably next best.

I like the subscript idea the least because: I don’t like the look of the 
syntax, keypaths feel more function-y than subscript-y, and it diminishes the 
flexibility of keypaths (as this thread has revealed).

> On Jul 11, 2017, at 7:56 PM, Karl Wagner  wrote:
> 
> 
>> On 12. Jul 2017, at 01:20, Robert Bennett > > wrote:
>> 
>> Well, if they really are first-class deferred method calls or member 
>> accesses, then do seem pretty function-y after all. Then again, if they were 
>> meant to be functions, it seems like their design would reflect that – 
>> instead of being used like subscripts, they would be called like functions, 
>> and since new syntax had to be created either way, the fact that they 
>> *weren't* just made into callable objects seems to indicate that that was 
>> not the intent, although I’d have to go back and read the discussion to see 
>> exactly what was discussed. 
> 
> I agree, and I suspect I’m not alone in disliking the subscript syntax.
> 
>> 
>> That said, I agree with Benjamin that having an `apply` method for KeyPath 
>> seems like the right way to make (or have made) keypaths work. 
>> keypath.apply(to: instance) (or keypath.evaluate(on:), or some other name 
>> that gets the idea across) reads just as nice as instance[keyPath: keypath] 
>> and has the added benefit of allowing collection.map(keypath.apply) at no 
>> cost. But it’s probably too late to even bother having a discussion about 
>> this, right?
> 
> I don’t think so. That’s why we have a beta. Real-world experience has shown 
> that we would often like to erase a KeyPath and use it as if it were a 
> closure. Maybe we want to pass a KeyPath as a parameter to a function such as 
> “map", which accepts a closure, or we want to set a variable with a 
> closure-type using a KeyPath. Those functions and stored properties don’t 
> care about the special properties of KeyPaths (e.g. that they are Codable) - 
> they only care that they are executable on a base object to produce a result. 
> You can wrap the key-paths inside closures, but it’s cumbersome and some 
> developers are asking for a shorthand to perform that erasure.
> 
> Personally, I would be in favour of making the erasure implicit and allowing 
> KeyPaths to be invoked using function-syntax:
> 
> // Invocation using function-syntax:
> 
> let _: Value = someClosure(parameter)
> let _: Value = someKeypath(parameter)
> 
> let _: Value = { $0.something.anotherThing }(parameter)
> let _: Value = (\MyObj.something.anotherThing)(parameter)
> 
> // Implicit erasure to closure-type:
> 
> class PrettyTableCell {
> let titleFormatter: (T) -> String
> }
> let cell= PrettyTableCell()
> cell.titleFormatter = \MyObj.something.name
> 
> let stuff = myObjects.map(\.something.anotherThing)
> 
> - Karl
> 
>> 
>>> On Jul 11, 2017, at 6:27 PM, Karl Wagner >> > wrote:
>>> 
>>> 
 On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
 > wrote:
 
 In general, I like the idea of making ordinary types callable (although 
 curried functions already accomplish this to some extent), but I hesitate 
 to bring this capability to keypaths because, well, they don’t really feel 
 like functions; I think the point of them is that they work like 
 subscripts, not functions. After all, before keypaths were added, there 
 was already an easy to make a function that does what a keypath does 
 (which makes me wonder whether keypaths were necessary in the first place, 
 but that ship has sailed). The only reason to add callable support to 
 keypaths is for use in map, which I don’t think justifies making them 
 callable.
 
 Also, since I brought this up, I’d like to be proved wrong about keypaths 
 – what use do they have that isn’t accomplished by the equivalent closure?
>>> 
>>> I can’t find a formal definition of a “keypath”, so let me explain how I 
>>> think of them:
>>> 
>>> Conceptually, I think I would define a KeyPath as a stateless, deferred 
>>> function application with one unbound argument (the “base"). Anything you 
>>> do with a KeyPath could be done with a closure of type (Base)->Value which 
>>> captures all other arguments (e.g. subscript/function parameters). The 
>>> major benefit that it has over 

Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Karl Wagner via swift-evolution

> On 12. Jul 2017, at 01:20, Robert Bennett  wrote:
> 
> Well, if they really are first-class deferred method calls or member 
> accesses, then do seem pretty function-y after all. Then again, if they were 
> meant to be functions, it seems like their design would reflect that – 
> instead of being used like subscripts, they would be called like functions, 
> and since new syntax had to be created either way, the fact that they 
> *weren't* just made into callable objects seems to indicate that that was not 
> the intent, although I’d have to go back and read the discussion to see 
> exactly what was discussed. 

I agree, and I suspect I’m not alone in disliking the subscript syntax.

> 
> That said, I agree with Benjamin that having an `apply` method for KeyPath 
> seems like the right way to make (or have made) keypaths work. 
> keypath.apply(to: instance) (or keypath.evaluate(on:), or some other name 
> that gets the idea across) reads just as nice as instance[keyPath: keypath] 
> and has the added benefit of allowing collection.map(keypath.apply) at no 
> cost. But it’s probably too late to even bother having a discussion about 
> this, right?

I don’t think so. That’s why we have a beta. Real-world experience has shown 
that we would often like to erase a KeyPath and use it as if it were a closure. 
Maybe we want to pass a KeyPath as a parameter to a function such as “map", 
which accepts a closure, or we want to set a variable with a closure-type using 
a KeyPath. Those functions and stored properties don’t care about the special 
properties of KeyPaths (e.g. that they are Codable) - they only care that they 
are executable on a base object to produce a result. You can wrap the key-paths 
inside closures, but it’s cumbersome and some developers are asking for a 
shorthand to perform that erasure.

Personally, I would be in favour of making the erasure implicit and allowing 
KeyPaths to be invoked using function-syntax:

// Invocation using function-syntax:

let _: Value = someClosure(parameter)
let _: Value = someKeypath(parameter)

let _: Value = { $0.something.anotherThing }(parameter)
let _: Value = (\MyObj.something.anotherThing)(parameter)

// Implicit erasure to closure-type:

class PrettyTableCell {
let titleFormatter: (T) -> String
}
let cell= PrettyTableCell()
cell.titleFormatter = \MyObj.something.name

let stuff = myObjects.map(\.something.anotherThing)

- Karl

> 
>> On Jul 11, 2017, at 6:27 PM, Karl Wagner  wrote:
>> 
>> 
>>> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
>>>  wrote:
>>> 
>>> In general, I like the idea of making ordinary types callable (although 
>>> curried functions already accomplish this to some extent), but I hesitate 
>>> to bring this capability to keypaths because, well, they don’t really feel 
>>> like functions; I think the point of them is that they work like 
>>> subscripts, not functions. After all, before keypaths were added, there was 
>>> already an easy to make a function that does what a keypath does (which 
>>> makes me wonder whether keypaths were necessary in the first place, but 
>>> that ship has sailed). The only reason to add callable support to keypaths 
>>> is for use in map, which I don’t think justifies making them callable.
>>> 
>>> Also, since I brought this up, I’d like to be proved wrong about keypaths – 
>>> what use do they have that isn’t accomplished by the equivalent closure?
>> 
>> I can’t find a formal definition of a “keypath”, so let me explain how I 
>> think of them:
>> 
>> Conceptually, I think I would define a KeyPath as a stateless, deferred 
>> function application with one unbound argument (the “base"). Anything you do 
>> with a KeyPath could be done with a closure of type (Base)->Value which 
>> captures all other arguments (e.g. subscript/function parameters). The major 
>> benefit that it has over a closure is identity (so you can put it in a 
>> dictionary or compare two keypaths), and that property that captures all of 
>> its parameters except the base, and that those parameters don’t have 
>> stateful side-effects. That makes it really handy for parallel execution and 
>> database predicates in ORMs.
>> 
>> There’s also another benefit of KeyPaths: they are de-/serialisable. Again, 
>> since it captures all of its (stateless) parameters, it itself is stateless 
>> and can be transferred to persistent storage or over a network.
>> 
>> You can actually see those constraints in the KeyPath proposal (which is 
>> part of what makes it such a great proposal, IMO): all captured parameters 
>> must be Hashable and Codable.
>> 
>> But to come back to your point - in all other respects a KeyPath is 
>> conceptually identical to a closure of type (Base)->Value. It’s like a 
>> specially-annotated closure, where it’s special construction syntax lets us 
>> statically verify that it’s a stateless, deferred function 

Re: [swift-evolution] [Rejected] SE-0030 Property Behaviors

2017-07-11 Thread Karl Wagner via swift-evolution

> On 11. Jul 2017, at 17:41, Wallacy via swift-evolution 
>  wrote:
> 
> When will be a good time to discuss this proposal again?

I think Apple's usual policy is that Swift 4 will ship with iOS 11 (so end of 
September, I think). Then they have a break, and sometime after that planning 
for Swift 5 starts. That’s probably the best time to bring it up so it can be 
weighed against other priorities.

So it’ll be a little while yet.

- Karl

> 
> 
> 
> Em qua, 24 de fev de 2016 às 04:14, Douglas Gregor via swift-evolution 
> > escreveu:
> The review of SE-0030 “Property Behaviors” ran from February 10...23, 2016. 
> The proposal in its current form is rejected:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
>  
> 
> 
> The core team believes that property behaviors are a worthwhile feature for 
> Swift, but it’s clear from the discussion that we as a community have not yet 
> converged on a design we are willing to commit to. It is therefore too early 
> to accept a proposal for this feature. We encourage the author to continue 
> refining the design and providing new proposal drafts for discussion, and 
> will schedule another public review when it looks like we are closer to 
> converging on a single design.
> 
>   Doug Gregor
>   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

___
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 Robert Bennett via swift-evolution
Well, if they really are first-class deferred method calls or member accesses, 
then do seem pretty function-y after all. Then again, if they were meant to be 
functions, it seems like their design would reflect that – instead of being 
used like subscripts, they would be called like functions, and since new syntax 
had to be created either way, the fact that they *weren't* just made into 
callable objects seems to indicate that that was not the intent, although I’d 
have to go back and read the discussion to see exactly what was discussed. 

That said, I agree with Benjamin that having an `apply` method for KeyPath 
seems like the right way to make (or have made) keypaths work. 
keypath.apply(to: instance) (or keypath.evaluate(on:), or some other name that 
gets the idea across) reads just as nice as instance[keyPath: keypath] and has 
the added benefit of allowing collection.map(keypath.apply) at no cost. But 
it’s probably too late to even bother having a discussion about this, right?

> On Jul 11, 2017, at 6:27 PM, Karl Wagner  wrote:
> 
> 
>> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
>>  wrote:
>> 
>> In general, I like the idea of making ordinary types callable (although 
>> curried functions already accomplish this to some extent), but I hesitate to 
>> bring this capability to keypaths because, well, they don’t really feel like 
>> functions; I think the point of them is that they work like subscripts, not 
>> functions. After all, before keypaths were added, there was already an easy 
>> to make a function that does what a keypath does (which makes me wonder 
>> whether keypaths were necessary in the first place, but that ship has 
>> sailed). The only reason to add callable support to keypaths is for use in 
>> map, which I don’t think justifies making them callable.
>> 
>> Also, since I brought this up, I’d like to be proved wrong about keypaths – 
>> what use do they have that isn’t accomplished by the equivalent closure?
> 
> I can’t find a formal definition of a “keypath”, so let me explain how I 
> think of them:
> 
> Conceptually, I think I would define a KeyPath as a stateless, deferred 
> function application with one unbound argument (the “base"). Anything you do 
> with a KeyPath could be done with a closure of type (Base)->Value which 
> captures all other arguments (e.g. subscript/function parameters). The major 
> benefit that it has over a closure is identity (so you can put it in a 
> dictionary or compare two keypaths), and that property that captures all of 
> its parameters except the base, and that those parameters don’t have stateful 
> side-effects. That makes it really handy for parallel execution and database 
> predicates in ORMs.
> 
> There’s also another benefit of KeyPaths: they are de-/serialisable. Again, 
> since it captures all of its (stateless) parameters, it itself is stateless 
> and can be transferred to persistent storage or over a network.
> 
> You can actually see those constraints in the KeyPath proposal (which is part 
> of what makes it such a great proposal, IMO): all captured parameters must be 
> Hashable and Codable.
> 
> But to come back to your point - in all other respects a KeyPath is 
> conceptually identical to a closure of type (Base)->Value. It’s like a 
> specially-annotated closure, where it’s special construction syntax lets us 
> statically verify that it’s a stateless, deferred function applicable to an 
> instance of the Base type.
> 
> The KeyPath proposal said that eventually, the core team would like to be 
> able to support arbitrary function calls in KeyPath expressions, too. For 
> example, it’s "not fair” that \MyObject.firstFiveElements and \MyObject[3] 
> are valid KeyPaths, but \MyObject.prefix(5) is not. It’s also expressible as 
> (Base)->Value, so conceptually it’s also a KeyPath and can be serialised and 
> whatnot.
> 
> - Karl 
> 
>>> On Jul 11, 2017, at 2:28 PM, Benjamin Herzog via swift-evolution 
>>>  wrote:
>>> 
>>> I still think using an operator for this conversation would neither 
>>> increase readability nor transparency. I think my mail on Sunday was lost, 
>>> so I paste the content here again. It referred to a suggestion to create a 
>>> possibility for KeyPath to act as a function which would bring other 
>>> benefits as well:
>>> 
>>> In Scala you can implement an apply method which makes it possible to call 
>>> an object just like a function. Example:
>>> 
>>> case class Foo(x: Int) {
>>>   def apply(y: Int) = x + y
>>> }
>>> 
>>> val foo = Foo(3)
>>> val bar = foo(4) // 7
>>> 
>>> That is similar to what you suggested to have a possibility to convert an 
>>> object to a closure getting called. And I totally see the point for this! I 
>>> think using a keyword or special name like apply is not a good idea because 
>>> it's not obvious what it does and it also makes it possible to just call 
>>> the method with its 

Re: [swift-evolution] [Pre-pitch] Allowing enums inside protocols?

2017-07-11 Thread Karl Wagner via swift-evolution

> On 9. Jul 2017, at 06:06, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Sat, Jul 8, 2017 at 10:52 PM, Jonathan Hull  > wrote:
> Do you know why it was never brought to a vote?  
> 
> If I had to guess, it would be because the core team decided it's not in 
> scope.

That’s pretty-much what happened. I wanted to allow nesting arbitrary types in 
protocols (e.g. FloatingPoint.Sign) and vice-versa (e.g. UITableView.Delegate). 
Wasn’t in scope.

> 
> As an aside not central to your question and not directed to you 
> specifically: There aren't votes in the evolution process; there are 
> community and core team reviews. The purpose, afaik, isn't to count the 
> number of replies that say "+1" or "-1."
>  
> I seem to remember us having a pretty good consensus.  I think we decided to 
> punt on nested generics by just not allowing nesting in them yet (which would 
> be compatible since that is what happens now too).  Then we would have a 
> second proposal to deal with generics/associated more carefully.
> 
>  I'm not aware of any proposal text that punts on nested generics.


Capturing generic type parameters between nested types works already. We lack 
the expressive ability to capture associated types between nested protocols (we 
would need generalised existentials). Capturing between generic types and 
associated types was controversial (and… yeah, that not exactly frictionless 
boundary between generic protocols and structural types is usually most 
people’s biggest problem with Swift’s generics).

Consider MyObject.Delegate:

- Should we create a new protocol for every type T (allowing one object to 
conform to both MyObject.Delegate and MyObject.Delegate)?, or
- Should there be one MyObject.Delegate protocol with an implicit 
associated-type “T”? e.g. "MyObject.Delegate where T == Int”. That would 
require "generalised existentials”.

So yeah, the proposal didn’t include capturing between nested protocols and 
types.

Also, I had some trouble nailing down the rules for when a nested type should 
be imported in to a conformer’s namespace. For example, you probably want 
Double.Sign to be an alias for FloatingPoint.Sign, but in general that might 
not always be true - especially if nested types and protocols can be added in 
extensions, things could get cluttered rather quickly. We don’t really have any 
formally-specified rules for unqualified lookup to take guidance from, either. 
In any case I think we should use the new protocol typealias lookup rules that 
appear to have popped up in Swift 3.2 - i.e. that typealiases inside the 
protocol body get inherited, but typealiases inside extensions don’t.

Long-term I really think we need to write down our rules for unqualified 
lookup. Something equivalent to this: 
http://en.cppreference.com/w/cpp/language/unqualified_lookup 


- Karl






___
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 Karl Wagner via swift-evolution

> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
>  wrote:
> 
> In general, I like the idea of making ordinary types callable (although 
> curried functions already accomplish this to some extent), but I hesitate to 
> bring this capability to keypaths because, well, they don’t really feel like 
> functions; I think the point of them is that they work like subscripts, not 
> functions. After all, before keypaths were added, there was already an easy 
> to make a function that does what a keypath does (which makes me wonder 
> whether keypaths were necessary in the first place, but that ship has 
> sailed). The only reason to add callable support to keypaths is for use in 
> map, which I don’t think justifies making them callable.
> 
> Also, since I brought this up, I’d like to be proved wrong about keypaths – 
> what use do they have that isn’t accomplished by the equivalent closure?
> 

I can’t find a formal definition of a “keypath”, so let me explain how I think 
of them:

Conceptually, I think I would define a KeyPath as a stateless, deferred 
function application with one unbound argument (the “base"). Anything you do 
with a KeyPath could be done with a closure of type (Base)->Value which 
captures all other arguments (e.g. subscript/function parameters). The major 
benefit that it has over a closure is identity (so you can put it in a 
dictionary or compare two keypaths), and that property that captures all of its 
parameters except the base, and that those parameters don’t have stateful 
side-effects. That makes it really handy for parallel execution and database 
predicates in ORMs.

There’s also another benefit of KeyPaths: they are de-/serialisable. Again, 
since it captures all of its (stateless) parameters, it itself is stateless and 
can be transferred to persistent storage or over a network.

You can actually see those constraints in the KeyPath proposal (which is part 
of what makes it such a great proposal, IMO): all captured parameters must be 
Hashable and Codable.

But to come back to your point - in all other respects a KeyPath is 
conceptually identical to a closure of type (Base)->Value. It’s like a 
specially-annotated closure, where it’s special construction syntax lets us 
statically verify that it’s a stateless, deferred function applicable to an 
instance of the Base type.

The KeyPath proposal said that eventually, the core team would like to be able 
to support arbitrary function calls in KeyPath expressions, too. For example, 
it’s "not fair” that \MyObject.firstFiveElements and \MyObject[3] are valid 
KeyPaths, but \MyObject.prefix(5) is not. It’s also expressible as 
(Base)->Value, so conceptually it’s also a KeyPath and can be serialised and 
whatnot.

- Karl 

>> On Jul 11, 2017, at 2:28 PM, Benjamin Herzog via swift-evolution 
>>  wrote:
>> 
>> I still think using an operator for this conversation would neither increase 
>> readability nor transparency. I think my mail on Sunday was lost, so I paste 
>> the content here again. It referred to a suggestion to create a possibility 
>> for KeyPath to act as a function which would bring other benefits as well:
>> 
>> In Scala you can implement an apply method which makes it possible to call 
>> an object just like a function. Example:
>> 
>> case class Foo(x: Int) {
>>def apply(y: Int) = x + y
>> }
>> 
>> val foo = Foo(3)
>> val bar = foo(4) // 7
>> 
>> That is similar to what you suggested to have a possibility to convert an 
>> object to a closure getting called. And I totally see the point for this! I 
>> think using a keyword or special name like apply is not a good idea because 
>> it's not obvious what it does and it also makes it possible to just call the 
>> method with its name: foo.apply(4).
>> 
>> However, having a protocol is kinda hard because it's not possible to have a 
>> flexible parameter list. Maybe having a method without a name? Swift example:
>> 
>> class Foo {
>>var x: Int
>>init(x: Int) { self.x = x }
>> 
>>func (y: Int) -> Int {
>>return self.x + y
>>}
>> }
>> 
>> let foo = Foo(x: 3)
>> let bar = foo(y: 4) // 7
>> 
>> I actually like that, would be like an anonymous function. It would also be 
>> possible to have multiple of those defined for one object (which would have 
>> to be unambiguous of course).
>> 
>> So getting back to KeyPath, it could look like this:
>> 
>> class KeyPath {
>>func (_ root: Root) -> Value {
>>return root[keyPath: self]
>>}  
>> }
>> 
>> I see that this would be a much bigger change and would not justify the 
>> syntactic sugar for map, flatMap, etc. But it would still be a nice addition 
>> to the Swift programming language, especially for KeyPath, transformers etc.
>> 
>> What do you think?
>> 
>> __
>> 
>> Benjamin Herzog
>> 
>> ___
>> swift-evolution mailing list
>> 

Re: [swift-evolution] [Pitch] BitPatternRepresentable

2017-07-11 Thread Dave Abrahams via swift-evolution

on Tue Jul 11 2017, Jens Persson  wrote:

> I've found it practical/necessary to write my own BitPatternRepresentable
> protocol and IMHO it feels like something that could have been added along
> with the improved numeric protocols of Swift 4.
>
> Would it make sense to add something like the following to the standard
> library?
>
> /// A type that can be converted to and from an associated BitPattern type.
> protocol BitPatternRepresentable {
> associatedtype BitPattern
> var bitPattern: BitPattern { get }
> init(bitPattern: BitPattern)
> }

As ever, my first question when a new protocol is proposed is, “what
generic algorithms rely on this protocol?”

inquiring-minds-wanna-know-ly y'rs,

-- 
-Dave

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


Re: [swift-evolution] [Request for Feedback] Providing defaults for reading and writing.

2017-07-11 Thread William Shipley via swift-evolution
You’re right, my current implementation doesn’t win anything over what you’re 
written -  in fact your technique is basically what I wrote at first.

I was trying to work towards encapsulating the behavior in the encoder/decoder 
so that the automatic init/encode methods could work, so I wanted to introduce 
my first (more manual) attempt and then say, here’s where I’d like to get with 
this.

-Wil


> On Jul 11, 2017, at 10:16 AM, Itai Ferber  wrote:
> 
> Hi Wil,
> 
> Thanks for putting this together! My biggest thought on this is — what does 
> this provide that you can’t already do yourself today?
> Since you have to go through the work to put together default values and 
> override init(from:) and encode(to:) to use them, I’m wondering whether this 
> saves you any work over doing something like the following:
> 
> struct Theme {
> private static let _defaultName = ""
> private static let _defaultStyles: [String] = []
> 
> public let name: String
> public let styles: [String]
> 
> private enum CodingKeys : String, CodingKey {
> case name
> case styles
> }
> 
> public init(from decoder: Decoder) throws {
> let container = try decoder.container(keyedBy: CodingKeys.self)
> name = try? decoder.decode(String.self, forKey: .name) ?? 
> Theme._defaultName
> styles = try? decoder.decode([String.self], forKey: .styles) ?? 
> Theme._defaultStyles
> }
> 
> public func encode(to encoder: Encoder) throws {
> var container = encoder.container(keyedBy: CodingKeys.self)
> if (name != Theme._defaultName) try container.encode(name, forKey: 
> .name)
> if (styles != Theme._defaultStyles) try container.encode(styles, 
> forKey: .styles)
> }
> }
> This reads just as clearly to me as the defaults: variation while having the 
> added benefit of low complexity and stronger type safety (as there’s no 
> as!-casting down from Any, which could fail).
> 
> Thoughts?
> 
> — Itai
> 
> On 10 Jul 2017, at 17:16, William Shipley via swift-evolution wrote:
> 
> Automatic substitution / removal of default values is very useful when 
> reading or writing a file, respectively, and should be supported by the 
>  family of protocols and objects:
> 
> • When reading, swapping in a default value for missing or corrupted values 
> makes it so hand-created or third-party-created files don’t have to write 
> every single value to make a valid file, and allows slightly corrupted files 
> to auto-repair (or get close, and let the user fix up any data that needs it 
> after) rather than completely fail to load. (Repairing on read creates a 
> virtuous cycle with user-created files, as the user will get _some_ feedback 
> on her input even if she’s messed up, for example, the type of one of the 
> properties.)
> 
> • When writing, providing a default value allows the container to skip keys 
> that don’t contain useful information. This can dramatically reduce file 
> sizes, but I think its other advantages are bigger wins: just like having 
> less source code makes a program easier to debug, having less “data code” 
> makes files easier to work with in every way — they’re easier to see 
> differences in, easier to determine corruption in, easier to edit by hand, 
> and easier to learn from.
> 
> 
> My first pass attempt at adding defaults to Codable looks like this:
> 
> 
> public class ReferencePieceFromModel : Codable {
> 
> // MARK: properties
> public let name: String = ""
> public let styles: [String] = []
> 
> 
> // MARK: 
> public required init(from decoder: Decoder) throws {
> let container = try decoder.container(keyedBy: CodingKeys.self)
> 
> self.name = container.decode(String.self, forKey: .name, defaults: type(of: 
> self).defaultsByCodingKey)
> self.styles = container.decode([String].self, forKey: .styles, defaults: 
> type(of: self).defaultsByCodingKey)
> }
> public func encode(to encoder: Encoder) throws {
> var container = encoder.container(keyedBy: CodingKeys.self)
> 
> try container.encode(name, forKey: .name, defaults: type(of: 
> self).defaultsByCodingKey)
> try container.encode(styles, forKey: .styles, defaults: type(of: 
> self).defaultsByCodingKey)
> }
> private static let defaultsByCodingKey: [CodingKeys : Any] = [
> .name : "",
> .styles : [String]()
> ]
> 
> 
> // MARK: private
> private enum CodingKeys : String, CodingKey {
> case name
> case styles
> }
> }
> 
> With just a couple additions to the Swift libraries:
> 
> extension KeyedDecodingContainer where Key : Hashable {
> func decode(_ type: T.Type, forKey key: Key, defaults: [Key : Any]) -> T 
> where T : Decodable {
> if let typedValueOptional = try? decodeIfPresent(T.self, forKey: key), let 
> typedValue = typedValueOptional {
> return typedValue
> } else {
> return defaults[key] as! T
> }
> }
> }
> 
> extension KeyedEncodingContainer where Key : Hashable {
> mutating func encode(_ value: T, forKey key: Key, defaults: [Key : Any]) 
> throws 

Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
In general, I like the idea of making ordinary types callable (although curried 
functions already accomplish this to some extent), but I hesitate to bring this 
capability to keypaths because, well, they don’t really feel like functions; I 
think the point of them is that they work like subscripts, not functions. After 
all, before keypaths were added, there was already an easy to make a function 
that does what a keypath does (which makes me wonder whether keypaths were 
necessary in the first place, but that ship has sailed). The only reason to add 
callable support to keypaths is for use in map, which I don’t think justifies 
making them callable.

Also, since I brought this up, I’d like to be proved wrong about keypaths – 
what use do they have that isn’t accomplished by the equivalent closure?

> On Jul 11, 2017, at 2:28 PM, Benjamin Herzog via swift-evolution 
>  wrote:
> 
> I still think using an operator for this conversation would neither increase 
> readability nor transparency. I think my mail on Sunday was lost, so I paste 
> the content here again. It referred to a suggestion to create a possibility 
> for KeyPath to act as a function which would bring other benefits as well:
> 
> In Scala you can implement an apply method which makes it possible to call an 
> object just like a function. Example:
> 
> case class Foo(x: Int) {
> def apply(y: Int) = x + y
> }
> 
> val foo = Foo(3)
> val bar = foo(4) // 7
> 
> That is similar to what you suggested to have a possibility to convert an 
> object to a closure getting called. And I totally see the point for this! I 
> think using a keyword or special name like apply is not a good idea because 
> it's not obvious what it does and it also makes it possible to just call the 
> method with its name: foo.apply(4).
> 
> However, having a protocol is kinda hard because it's not possible to have a 
> flexible parameter list. Maybe having a method without a name? Swift example:
> 
> class Foo {
> var x: Int
> init(x: Int) { self.x = x }
>
> func (y: Int) -> Int {
> return self.x + y
> }
> }
> 
> let foo = Foo(x: 3)
> let bar = foo(y: 4) // 7
> 
> I actually like that, would be like an anonymous function. It would also be 
> possible to have multiple of those defined for one object (which would have 
> to be unambiguous of course).
> 
> So getting back to KeyPath, it could look like this:
> 
> class KeyPath {
> func (_ root: Root) -> Value {
> return root[keyPath: self]
> }  
> }
> 
> I see that this would be a much bigger change and would not justify the 
> syntactic sugar for map, flatMap, etc. But it would still be a nice addition 
> to the Swift programming language, especially for KeyPath, transformers etc.
> 
> What do you think?
> 
> __
> 
> 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


Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Benjamin Herzog via swift-evolution
I still think using an operator for this conversation would neither increase 
readability nor transparency. I think my mail on Sunday was lost, so I paste 
the content here again. It referred to a suggestion to create a possibility for 
KeyPath to act as a function which would bring other benefits as well:
In Scala you can implement an apply method which makes it possible to call an 
object just like a function. Example:
case class Foo(x: Int) {
def apply(y: Int) = x + y
}

val foo = Foo(3)
val bar = foo(4) // 7

That is similar to what you suggested to have a possibility to convert an 
object to a closure getting called. And I totally see the point for this! I 
think using a keyword or special name like apply is not a good idea because 
it's not obvious what it does and it also makes it possible to just call the 
method with its name: foo.apply(4).
However, having a protocol is kinda hard because it's not possible to have a 
flexible parameter list. Maybe having a method without a name? Swift example:
class Foo {
var x: Int
init(x: Int) { self.x = x }
   
func (y: Int) -> Int {
return self.x + y
}
}

let foo = Foo(x: 3)
let bar = foo(y: 4) // 7

I actually like that, would be like an anonymous function. It would also be 
possible to have multiple of those defined for one object (which would have to 
be unambiguous of course).
So getting back to KeyPath, it could look like this:

class KeyPath {
func (_ root: Root) -> Value {
return root[keyPath: self]
}  
}

I see that this would be a much bigger change and would not justify the 
syntactic sugar for map, flatMap, etc. But it would still be a nice addition to 
the Swift programming language, especially for KeyPath, transformers etc.
What do you think?

__

Benjamin Herzog

___
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 Robert Bennett via swift-evolution
This is also the case for $0, although I suppose that since $0 is only valid 
inside a closure, LLDB has some context with which to disambiguate Swift’s $0 
from LLDB’s, context it wouldn’t have with $keyPath. That said, there are 
probably solutions to this, like requiring a backslash before a Swift dollar 
sign to disambiguate from an LLDB dollar sign. Or something else. Designing the 
language with constraints imposed by the debugger seems unduly restrictive, 
though – surely the debugger should be subservient to the language, not the 
other way around.

> On Jul 11, 2017, at 12:44 PM, BJ Homer  wrote:
> 
> ‘$' 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


[swift-evolution] [Review] SE-0181: Package Manager C/C++ Language Standard Support

2017-07-11 Thread Daniel Dunbar via swift-evolution
Hello Swift community,

The review of SE-0181: Package Manager C/C++ Language Standard Support begins 
now and runs through July 14th, 2017.

The proposal is available here:

  
https://github.com/apple/swift-evolution/blob/master/proposals/0181-package-manager-cpp-language-version.md

Reviews are an important part of the Swift evolution process. All reviews 
should be sent to the swift-build-dev and swift-evolution mailing lists at

  https://lists.swift.org/mailman/listinfo/swift-build-dev 

  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/0181-package-manager-cpp-language-version.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,
Daniel Dunbar (Review Manager)
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Request for Feedback] Providing defaults for reading and writing.

2017-07-11 Thread Itai Ferber via swift-evolution

Hi Wil,

Thanks for putting this together! My biggest thought on this is — what 
does this provide that you can’t already do yourself today?
Since you have to go through the work to put together default values and 
override `init(from:)` and `encode(to:)` to use them, I’m wondering 
whether this saves you any work over doing something like the following:


```swift
struct Theme {
private static let _defaultName = ""
private static let _defaultStyles: [String] = []

public let name: String
public let styles: [String]

private enum CodingKeys : String, CodingKey {
case name
case styles
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try? decoder.decode(String.self, forKey: .name) ?? 
Theme._defaultName
styles = try? decoder.decode([String.self], forKey: .styles) ?? 
Theme._defaultStyles

}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if (name != Theme._defaultName) try container.encode(name, 
forKey: .name)
if (styles != Theme._defaultStyles) try 
container.encode(styles, forKey: .styles)

}
}
```

This reads just as clearly to me as the `defaults:` variation while 
having the added benefit of low complexity and stronger type safety (as 
there’s no `as!`-casting down from `Any`, which could fail).


Thoughts?

— Itai

On 10 Jul 2017, at 17:16, William Shipley via swift-evolution wrote:

Automatic substitution / removal of default values is very useful when 
reading or writing a file, respectively, and should be supported by 
the  family of protocols and objects:


• When reading, swapping in a default value for missing or corrupted 
values makes it so hand-created or third-party-created files don’t 
have to write every single value to make a valid file, and allows 
slightly corrupted files to auto-repair (or get close, and let the 
user fix up any data that needs it after) rather than completely fail 
to load. (Repairing on read creates a virtuous cycle with user-created 
files, as the user will get _some_ feedback on her input even if 
she’s messed up, for example, the type of one of the properties.)


• When writing, providing a default value allows the container to 
skip keys that don’t contain useful information. This can 
dramatically reduce file sizes, but I think its other advantages are 
bigger wins: just like having less source code makes a program easier 
to debug, having less “data code” makes files easier to work with 
in every way — they’re easier to see differences in, easier to 
determine corruption in, easier to edit by hand, and easier to learn 
from.



My first pass attempt at adding defaults to Codable looks like this:


public class ReferencePieceFromModel : Codable {

// MARK: properties
public let name: String = ""
public let styles: [String] = []


// MARK: 
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: 
CodingKeys.self)


self.name = container.decode(String.self, forKey: .name, 
defaults: type(of: self).defaultsByCodingKey)
self.styles = container.decode([String].self, forKey: .styles, 
defaults: type(of: self).defaultsByCodingKey)

}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(name, forKey: .name, defaults: type(of: 
self).defaultsByCodingKey)
try container.encode(styles, forKey: .styles, defaults: 
type(of: self).defaultsByCodingKey)

}
private static let defaultsByCodingKey: [CodingKeys : Any] = [
.name : "",
.styles : [String]()
]


// MARK: private
private enum CodingKeys : String, CodingKey {
case name
case styles
}
}

With just a couple additions to the Swift libraries:

extension KeyedDecodingContainer where Key : Hashable {
func decode(_ type: T.Type, forKey key: Key, defaults: [Key : 
Any]) -> T where T : Decodable {
if let typedValueOptional = try? decodeIfPresent(T.self, 
forKey: key), let typedValue = typedValueOptional {

return typedValue
} else {
return defaults[key] as! T
}
}
}

extension KeyedEncodingContainer where Key : Hashable {
mutating func encode(_ value: T, forKey key: Key, defaults: 
[Key : Any]) throws where T : Encodable & Equatable {

if value != (defaults[key] as! T) {
try encode(value, forKey: key)
}
}

mutating func encode(_ value: [T], forKey key: Key, defaults: 
[Key : Any]) throws where T : Encodable & Equatable { // I AM SO SORRY 
THIS IS ALL I COULD FIGURE OUT TO MAKE [String] WORK!

if value != (defaults[key] as! [T]) {
try encode(value, forKey: key)
}
}
}


(Note the horrible hack on KeyedEncodingContainer where I 

[swift-evolution] Fwd: [Pitch] Guard/Catch

2017-07-11 Thread Christopher Kornher via swift-evolution


Begin forwarded message:

From: Christopher Kornher 
Subject: Re: [swift-evolution] [Pitch] Guard/Catch
Date: July 10, 2017 at 5:10:15 PM MDT
To: Elviro Rocca 

This messages was modified from the original accidentally sent out privately, 
earlier.

FYI this works today in Xcode 9.0 beta 2 playgrounds:

```
class X {
init() throws {}

func foo() {
print( "Things succeeded" )
}
}

func bar() throws -> X  { return try X() }


func f()
{
guard let x1:X = try? X(), let x2:X = try? bar() else {
print( "Things failed ")
return
}

x1.foo()
x2.foo()
}

f()// works
```


Most of the examples of this proposed feature don’t handle the exceptions other 
than to perform an early return. 
So, without handing exceptions,  the only unhandled case is a non-returning 
throwing function or init:
 
```
class X {
init() throws {}

func foo() {
print( "Things succeeded" )
}
}

func bar() throws{ let _ =  try X() }


func f()
{
do {
try bar()
} catch {
return
}

guard let x:X = try? X() else {
print( "Things failed ")
return
}

x.foo()
}

f()// works
```

Having to call a throwing, Void method before performing the rest of a 
non-throwing function (or closure ) seems like an edge case to me. Perhaps I am 
just biased by my experience. I have not created or used many throwing 
initializers and certainly none in guard statements, and if they were in guard 
statements, the need to handle exceptions differently from any other guard 
failure seems ever more unlikely.

I don’t think that the small rightward drift of exception handling is onerous. 
It is hardly like the “pyramid of doom” that ```guard``` was created to fix.

```
func f( y:Int? = nil )
{
do {
try bar()
let x:X = try X()

guard let y = y else {
print( "No y")
return
}

x.foo()
print( "y=\(y)")
} catch {
// Handle some exceptions.
return
}
}
```

On Jul 10, 2017, at 1:45 AM, Elviro Rocca via swift-evolution 
> wrote:

This is not a sugar proposal, in the same way as "guard" is not syntactic 
sugar, because it requires exiting the scope on the else branch, adding 
expressive power and safety to the call: also, the sugary part is pretty 
important because it avoids nested parentheses and very clearly states that if 
the guard condition is not fulfilled, the execution will not reach the next 
lines of code. Guard is useful to push the programmer to at least consider an 
early return instead of branching code paths, to achieve better clarity, 
readability and lower complexity, and I suspect is one of the best Swift 
features for many people.

Also, the case that the proposal aims to cover is not an edge case at all for a 
lot of people, including me. Rethrowing an error is something that I almost 
never do, and I consider the "umbrella" do/catch at the top of the call stack 
an anti-pattern, but I understand that many people like it and I'm not arguing 
against it. I am arguing in favor of having options and not pushing a 
particular style onto programmers, and for my (and many people's) style, a 
guard/catch with forced return is an excellent idea. In fact you seem to agree 
on the necessity of some kind of forced-returnish catch but your elaborations 
don't seem (to me) much better than the proposal itself.

Dave DeLong raised the point of weird behavior in the case of a function like:


func doSomething() throws → Result? { … }


In this case, what would the type of x be?


guard let x = try doSomething() catch { /// handle and return }


Simple, it would be Optional. I don't find this confusing at all, and 
if the idea that just by seeing "guard let" we should expect a non-Optional is 
somehow diffused, I think it's better to eradicate it.

First of all, if I'm returning an optional from a throwing function, it's 
probably the case that I want the Optional to be there in the returned value: 
the only reason why I would consider doing that is if the semantics of Optional 
are pretty meaningful in that case. For example, when parsing a JSON in which I 
expect a String or null to be at a certain key:


extension String: Error {}

func parseString(in dict: [String:Any], at key: String) throws -> String? {
guard let x = dict[key] else { throw "No value found at '\(key)' in 
\(dict)" }
if let x = x as? String { return x }
if let x = x as? NSNull { return nil }
throw "Value at '\(key)' in \(dict) is not 'string' or 'null"
}


Thus, if I'm returning an Optional from a throwing function it means that I 
want to clearly distinguish the two cases, so they shouldn't be collapsed in a 
single call:


guard let x = try doSomething() catch { /// handle and return }
guard let x = x else { 

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] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
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


Re: [swift-evolution] [Rejected] SE-0030 Property Behaviors

2017-07-11 Thread Wallacy via swift-evolution
When will be a good time to discuss this proposal again?



Em qua, 24 de fev de 2016 às 04:14, Douglas Gregor via swift-evolution <
swift-evolution@swift.org> escreveu:

> The review of SE-0030 “Property Behaviors” ran from February 10...23,
> 2016. The proposal in its current form is *rejected*:
>
>
> https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
>
> The core team believes that property behaviors are a worthwhile feature
> for Swift, but it’s clear from the discussion that we as a community have
> not yet converged on a design we are willing to commit to. It is therefore
> too early to accept a proposal for this feature. We encourage the author to
> continue refining the design and providing new proposal drafts for
> discussion, and will schedule another public review when it looks like we
> are closer to converging on a single design.
>
> Doug Gregor
> Review Manager
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Elviro Rocca via swift-evolution
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] [Pitch] BitPatternRepresentable

2017-07-11 Thread Jens Persson via swift-evolution
I've found it practical/necessary to write my own BitPatternRepresentable
protocol and IMHO it feels like something that could have been added along
with the improved numeric protocols of Swift 4.

Would it make sense to add something like the following to the standard
library?

/// A type that can be converted to and from an associated BitPattern type.
protocol BitPatternRepresentable {
associatedtype BitPattern
var bitPattern: BitPattern { get }
init(bitPattern: BitPattern)
}

I think it's preferable to keep the conforming type's BitPatterns to the
most basic (most "BitPattern-like" types) so eg
UInt8, UInt16, UInt32, UInt64
rather than
Int8, Int16, Int32, Int64
and, depending on platform
UInt64, UInt32
rather than
Int or UInt.

PS

// Double and Float already fulfill the requirements of
BitPatternRepresentable so:

extension Double : BitPatternRepresentable {}
extension Float : BitPatternRepresentable {}

// And here is the rest of the types that I've used:

extension UInt8 : BitPatternRepresentable {
var bitPattern: UInt8 { return self }
init(bitPattern: UInt8) { self = bitPattern }
}
extension UInt16 : BitPatternRepresentable {
var bitPattern: UInt16 { return self }
init(bitPattern: UInt16) { self = bitPattern }
}
extension UInt32 : BitPatternRepresentable {
var bitPattern: UInt32 { return self }
init(bitPattern: UInt32) { self = bitPattern }
}
extension UInt64 : BitPatternRepresentable {
var bitPattern: UInt64 { return self }
init(bitPattern: UInt64) { self = bitPattern }
}
#if arch(x86_64) || arch(arm64)
extension Int : BitPatternRepresentable {
var bitPattern: UInt64 { return UInt64(UInt.init(bitPattern: self))
}
init(bitPattern: UInt64) { self = Int(Int64(bitPattern:
bitPattern)) }
}
extension UInt : BitPatternRepresentable {
var bitPattern: UInt64 { return UInt64(self) }
init(bitPattern: UInt64) { self = UInt(bitPattern) }
}
#elseif arch(i386) || arch(arm)
extension Int : BitPatternRepresentable {
var bitPattern: UInt32 { return UInt32(UInt.init(bitPattern: self))
}
init(bitPattern: UInt32) { self = Int(Int32(bitPattern:
bitPattern)) }
}
extension UInt : BitPatternRepresentable {
var bitPattern: UInt32 { return UInt32(self) }
init(bitPattern: UInt32) { self = UInt(bitPattern) }
}
#endif


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


Re: [swift-evolution] [Pitch] BitPatternRepresentable

2017-07-11 Thread Jens Persson via swift-evolution
Oh, I forgot the signed IntN types:

extension Int8 : BitPatternRepresentable {
var bitPattern: UInt8 { return UInt8(bitPattern: self) }
init(bitPattern: UInt8) { self = Int8(bitPattern: bitPattern) }
}
extension Int16 : BitPatternRepresentable {
var bitPattern: UInt16 { return UInt16(bitPattern: self) }
init(bitPattern: UInt16) { self = Int16(bitPattern: bitPattern) }
}
extension Int32 : BitPatternRepresentable {
var bitPattern: UInt32 { return UInt32(bitPattern: self) }
init(bitPattern: UInt32) { self = Int32(bitPattern: bitPattern) }
}
extension Int64 : BitPatternRepresentable {
var bitPattern: UInt64 { return UInt64(bitPattern: self) }
init(bitPattern: UInt64) { self = Int64(bitPattern: bitPattern) }
}


On Tue, Jul 11, 2017 at 1:57 PM, Jens Persson  wrote:

> I've found it practical/necessary to write my own BitPatternRepresentable
> protocol and IMHO it feels like something that could have been added along
> with the improved numeric protocols of Swift 4.
>
> Would it make sense to add something like the following to the standard
> library?
>
> /// A type that can be converted to and from an associated BitPattern type.
> protocol BitPatternRepresentable {
> associatedtype BitPattern
> var bitPattern: BitPattern { get }
> init(bitPattern: BitPattern)
> }
>
> I think it's preferable to keep the conforming type's BitPatterns to the
> most basic (most "BitPattern-like" types) so eg
> UInt8, UInt16, UInt32, UInt64
> rather than
> Int8, Int16, Int32, Int64
> and, depending on platform
> UInt64, UInt32
> rather than
> Int or UInt.
>
> PS
>
> // Double and Float already fulfill the requirements of
> BitPatternRepresentable so:
>
> extension Double : BitPatternRepresentable {}
> extension Float : BitPatternRepresentable {}
>
> // And here is the rest of the types that I've used:
>
> extension UInt8 : BitPatternRepresentable {
> var bitPattern: UInt8 { return self }
> init(bitPattern: UInt8) { self = bitPattern }
> }
> extension UInt16 : BitPatternRepresentable {
> var bitPattern: UInt16 { return self }
> init(bitPattern: UInt16) { self = bitPattern }
> }
> extension UInt32 : BitPatternRepresentable {
> var bitPattern: UInt32 { return self }
> init(bitPattern: UInt32) { self = bitPattern }
> }
> extension UInt64 : BitPatternRepresentable {
> var bitPattern: UInt64 { return self }
> init(bitPattern: UInt64) { self = bitPattern }
> }
> #if arch(x86_64) || arch(arm64)
> extension Int : BitPatternRepresentable {
> var bitPattern: UInt64 { return UInt64(UInt.init(bitPattern:
> self)) }
> init(bitPattern: UInt64) { self = Int(Int64(bitPattern:
> bitPattern)) }
> }
> extension UInt : BitPatternRepresentable {
> var bitPattern: UInt64 { return UInt64(self) }
> init(bitPattern: UInt64) { self = UInt(bitPattern) }
> }
> #elseif arch(i386) || arch(arm)
> extension Int : BitPatternRepresentable {
> var bitPattern: UInt32 { return UInt32(UInt.init(bitPattern:
> self)) }
> init(bitPattern: UInt32) { self = Int(Int32(bitPattern:
> bitPattern)) }
> }
> extension UInt : BitPatternRepresentable {
> var bitPattern: UInt32 { return UInt32(self) }
> init(bitPattern: UInt32) { self = UInt(bitPattern) }
> }
> #endif
>
>
> /Jens
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Guard/Catch

2017-07-11 Thread Elviro Rocca via swift-evolution
Not sure what you mean here. A guard/catch would allow me to handle the error 
in the catch, something that (of course) cannot be done with "try?", so 
guard/else with "try?" is not a solution. And of course returning in the catch 
side of a do/catch is like returning in the else side of a if/else, but that's 
what "guard" is about, so I probably didn't understand what's your point here.


Elviro


> Il giorno 11 lug 2017, alle ore 01:10, Christopher Kornher  
> ha scritto:
> 
> FYI this works today in Xcode 9.0 beta 2 playgrounds:
> 
> ```
> class X {
> init() throws {}
> 
> func foo() {
> print( "Things succeeded" )
> }
> }
> 
> func bar() throws -> X  { return try X() }
> 
> 
> func f()
> {
> guard let x1:X = try? X(), let x2:X = try? bar() else {
> print( "Things failed ")
> return
> }
> 
> x1.foo()
> x2.foo()
> }
> 
> f()// works
> ```
> 
> So the only unhandled case is a non-returning throwing function or init:
>  
> ```
> class X {
> init() throws {}
> 
> func foo() {
> print( "Things succeeded" )
> }
> }
> 
> func bar() throws{ let _ =  try X() }
> 
> 
> func f()
> {
> do {
> try bar()
> } catch {
> return
> }
> 
> guard let x:X = try? X() else {
> print( "Things failed ")
> return
> }
> 
> x.foo()
> }
> 
> f()// works
> ```
> 
> Having to call a throwing, Void method before performing the rest of a 
> function seems like an edge case to me 
> 
> 
>> On Jul 10, 2017, at 1:45 AM, Elviro Rocca via swift-evolution 
>> > wrote:
>> 
>> This is not a sugar proposal, in the same way as "guard" is not syntactic 
>> sugar, because it requires exiting the scope on the else branch, adding 
>> expressive power and safety to the call: also, the sugary part is pretty 
>> important because it avoids nested parentheses and very clearly states that 
>> if the guard condition is not fulfilled, the execution will not reach the 
>> next lines of code. Guard is useful to push the programmer to at least 
>> consider an early return instead of branching code paths, to achieve better 
>> clarity, readability and lower complexity, and I suspect is one of the best 
>> Swift features for many people.
>> 
>> Also, the case that the proposal aims to cover is not an edge case at all 
>> for a lot of people, including me. Rethrowing an error is something that I 
>> almost never do, and I consider the "umbrella" do/catch at the top of the 
>> call stack an anti-pattern, but I understand that many people like it and 
>> I'm not arguing against it. I am arguing in favor of having options and not 
>> pushing a particular style onto programmers, and for my (and many people's) 
>> style, a guard/catch with forced return is an excellent idea. In fact you 
>> seem to agree on the necessity of some kind of forced-returnish catch but 
>> your elaborations don't seem (to me) much better than the proposal itself.
>> 
>> Dave DeLong raised the point of weird behavior in the case of a function 
>> like:
>> 
>> 
>> func doSomething() throws → Result? { … }
>> 
>> 
>> In this case, what would the type of x be?
>> 
>> 
>> guard let x = try doSomething() catch { /// handle and return }
>> 
>> 
>> Simple, it would be Optional. I don't find this confusing at all, 
>> and if the idea that just by seeing "guard let" we should expect a 
>> non-Optional is somehow diffused, I think it's better to eradicate it.
>> 
>> First of all, if I'm returning an optional from a throwing function, it's 
>> probably the case that I want the Optional to be there in the returned 
>> value: the only reason why I would consider doing that is if the semantics 
>> of Optional are pretty meaningful in that case. For example, when parsing a 
>> JSON in which I expect a String or null to be at a certain key:
>> 
>> 
>> extension String: Error {}
>> 
>> func parseString(in dict: [String:Any], at key: String) throws -> String? {
>>  guard let x = dict[key] else { throw "No value found at '\(key)' in 
>> \(dict)" }
>>  if let x = x as? String { return x }
>>  if let x = x as? NSNull { return nil }
>>  throw "Value at '\(key)' in \(dict) is not 'string' or 'null"
>> }
>> 
>> 
>> Thus, if I'm returning an Optional from a throwing function it means that I 
>> want to clearly distinguish the two cases, so they shouldn't be collapsed in 
>> a single call:
>> 
>> 
>> guard let x = try doSomething() catch { /// handle and return }
>> guard let x = x else { /// handle and return }
>> 
>> 
>> Also, if a function returns something like "Int??", a guard-let (or if-let) 
>> on the returned value of that function will still bind an "Int?", thus 
>> unwrapping only "one level" of optional. If-let and guard-let, as of today, 
>> just unwrap a single optional level, an do not guaranteed at all that the 
>> bound value is not optional.
>> 
>> To me guard-let