Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-14 Thread Howard Lovatt via swift-users
I am assuming Never is the subtype of all types, because any function
regardless of it's return type, including Void, can return Never.

On Fri, 13 Jan 2017 at 6:32 pm, Pierre Monod-Broca <
pierremonodbr...@gmail.com> wrote:

> @Howard
> I was thinking the same about the constraint.
>
> Does that mean that Never should be a subtype of Error (maybe it is
> already) ? Else you couldn't say throws(Never) or FSTore
>
> @Howard
> I'm not sure about <>, it should stay reserved for generics, IMHO.
>
> Pierre
>
> Le 13 janv. 2017 à 01:11, Howard Lovatt via swift-users <
> swift-users@swift.org> a écrit :
>
> @Anton, Yes that would work and we would get typed throws, which I like.
> As an aside, I think E would have to be constrained to be an Error, ` Error>`, and maybe `throws` reads better because you are used to types
> in angle brackets.
>
>   -- Howard.
>
>
>
> On 13 January 2017 at 08:32, Anton Zhilin  wrote:
>
> The best way to deal with such situations should be typed throws. Then
> rethrows should be removed and replaced with generics in throws clause. E
> == Never ⇔ function does not throw.
>
>
> struct FStore {
>
> let f: () throws(E) -> Void
>
> init(_ f: @escaping () throws(E) -> Void) { self.f = f }
>
> func call() throws(E) { try f() }
>
> }
>
>
>
> let store = FStore({ print("Hello") })
>
> store.call()
>
> [Phase2]
>
>
> ​
>
>
>
>
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
> --
-- Howard.
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Pierre Monod-Broca via swift-users
@Howard
I was thinking the same about the constraint.

Does that mean that Never should be a subtype of Error (maybe it is already) ? 
Else you couldn't say throws(Never) or FSTore

@Howard
I'm not sure about <>, it should stay reserved for generics, IMHO.

Pierre

> Le 13 janv. 2017 à 01:11, Howard Lovatt via swift-users 
>  a écrit :
> 
> @Anton, Yes that would work and we would get typed throws, which I like. As 
> an aside, I think E would have to be constrained to be an Error, ` Error>`, and maybe `throws` reads better because you are used to types in 
> angle brackets.
> 
>   -- Howard.
> 
>> On 13 January 2017 at 08:32, Anton Zhilin  wrote:
>> The best way to deal with such situations should be typed throws. Then 
>> rethrows should be removed and replaced with generics in throws clause. E == 
>> Never ⇔ function does not throw.
>> 
>> struct FStore {
>> let f: () throws(E) -> Void
>> init(_ f: @escaping () throws(E) -> Void) { self.f = f }
>> func call() throws(E) { try f() }
>> }
>> 
>> let store = FStore({ print("Hello") })
>> store.call()
>> [Phase2]
>> 
> 
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Howard Lovatt via swift-users
@Slava,

I'm imagining that the compiler does much the same as Anton suggested, e.g.
Anton's:

struct FStore {
let f: () throws -> Void
init(_ f: @escaping () throws -> Void) { self.f = f }
func call() throws { try f() }
}

Is much the same as my:

struct FStore {
let f: () throws -> Void
init(_ f: @escaping () throws -> Void) { self.f = f }
func call() throws { try f() }
}

>From a compiler point of view.

The idea is that the compiler reuses some of its existing generic's
infrastructure. The main differences between my proposal and Anton's is
that because mine doesn't use a typed throw, E can only be 'AnyError' (any
type that implements Error) or Never, and E is not explicit. The
throws/rethrows distinction just becomes a compiler optimization in both
cases.

  -- Howard.

On 13 January 2017 at 10:42, Slava Pestov  wrote:

>
> On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution <
> swift-evolut...@swift.org> wrote:
>
> Another possibility, other than generics, would be to drop rethrows all
> together and have the compiler infer if a throw is possible or not,
> including:
>
> struct FStore {
> let f: () throws -> Void
> func call() throws { try f() }
> }
>
> The compiler can make two versions, one if f can throw and one if it
> definitely doesn't.
>
>
> It seems that this approach is impractical, because you either have to
> compile two versions of every function, or make all function bodies
> available for inlining, which is a non-starter for a stable ABI.
>
> Slava
>
>
> Just a thought.
>
> On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch 
> wrote:
>
>> Moving to swift-users list.
>>
>> No, there's no way to do this today. The point of rethrows is that within
>> one call site, "f(block)" can be treated as throwing if the block throws,
>> or not throwing if the block doesn't throw. In your example, once the
>> FStore object is constructed, the information about the original passed-in
>> function is lost, so the caller has no way to know whether call() can throw
>> or not.
>>
>> If this *were* possible, the information would somehow need to be encoded
>> in the type system when creating FStore(f: block). That would require
>> something like dependent typing, or generic-param-based-rethrows, e.g.
>>
>> struct FStore Void> {  // made-up syntax
>> let f: T
>> func call() rethrows(T) { try f() }  // throws-ness of this function
>> depends on throws-ness of T
>> }
>>
>>
>>
>> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution > evolut...@swift.org> wrote:
>>
>> Hi,
>>
>> If I have an escaping function that I store and then call, I need to
>> declare the calling function as throwing, not rethrowing. EG:
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> struct FStore {
>> let f: () throws -> Void
>> init(f: @escaping () throws -> Void) { self.f = f }
>> func call() throws { try f() } // Can't put rethrows here - have
>> to use throws
>> }
>> Is there a better solution?
>>
>> Thanks for any suggestions,
>>
>>   -- Howard.
>>
>>
>>
>>
>>
>> ___
>>
>>
>> swift-evolution mailing list
>>
>>
>> swift-evolut...@swift.org
>>
>>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>>
>>
>>
>> --
> -- Howard.
> ___
> swift-evolution mailing list
> swift-evolut...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Howard Lovatt via swift-users
@Anton, Yes that would work and we would get typed throws, which I like. As
an aside, I think E would have to be constrained to be an Error, ``, and maybe `throws` reads better because you are used to types
in angle brackets.

  -- Howard.

On 13 January 2017 at 08:32, Anton Zhilin  wrote:

> The best way to deal with such situations should be typed throws. Then
> rethrows should be removed and replaced with generics in throws clause. E
> == Never ⇔ function does not throw.
>
> struct FStore {
> let f: () throws(E) -> Void
> init(_ f: @escaping () throws(E) -> Void) { self.f = f }
> func call() throws(E) { try f() }
> }
>
> let store = FStore({ print("Hello") })
> store.call()
>
> [Phase2]
> ​
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Slava Pestov via swift-users

> On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Another possibility, other than generics, would be to drop rethrows all 
> together and have the compiler infer if a throw is possible or not, including:
> 
> struct FStore {
> let f: () throws -> Void
> func call() throws { try f() }
> }
> 
> The compiler can make two versions, one if f can throw and one if it 
> definitely doesn't. 

It seems that this approach is impractical, because you either have to compile 
two versions of every function, or make all function bodies available for 
inlining, which is a non-starter for a stable ABI.

Slava

> 
> Just a thought. 
> 
> On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch  > wrote:
> Moving to swift-users list.
> 
> No, there's no way to do this today. The point of rethrows is that within one 
> call site, "f(block)" can be treated as throwing if the block throws, or not 
> throwing if the block doesn't throw. In your example, once the FStore object 
> is constructed, the information about the original passed-in function is 
> lost, so the caller has no way to know whether call() can throw or not.
> 
> If this *were* possible, the information would somehow need to be encoded in 
> the type system when creating FStore(f: block). That would require something 
> like dependent typing, or generic-param-based-rethrows, e.g.
> 
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function 
> depends on throws-ness of T
> }
> 
> 
> 
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution 
> mailto:swift-evolut...@swift.org>> wrote:
> Hi,
> 
> If I have an escaping function that I store and then call, I need to declare 
> the calling function as throwing, not rethrowing. EG:
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have to 
> use throws
> }
> 
> Is there a better solution?
> 
> Thanks for any suggestions,
> 
>   -- Howard.
> 
> 
> 
> 
> 
> ___
> 
> 
> swift-evolution mailing list
> 
> 
> swift-evolut...@swift.org 
> 
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 
> 
> 
> 
> 
> -- 
> -- Howard.
> ___
> swift-evolution mailing list
> swift-evolut...@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-12 Thread Anton Zhilin via swift-users
The best way to deal with such situations should be typed throws. Then
rethrows should be removed and replaced with generics in throws clause. E
== Never ⇔ function does not throw.

struct FStore {
let f: () throws(E) -> Void
init(_ f: @escaping () throws(E) -> Void) { self.f = f }
func call() throws(E) { try f() }
}

let store = FStore({ print("Hello") })
store.call()

[Phase2]
​
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-11 Thread Howard Lovatt via swift-users
Yes, I have used Result in the past.

In this case I wanted to use throws because that is what functions like map
do.

Looks like I will have to stick with throwing, not too bad since the
overhead is reasonably low.

On Wed, 11 Jan 2017 at 8:03 am, T.J. Usiyan  wrote:

> I suggest using an enum to represent success and failure. It's usually
> referred to as `Result`. It might seem weird for the closure that you
> presented as an example, since it would be Result, but it properly
> captures the possibility of having thrown.
>
> ``` swift
> enum UselessError : Swift.Error {
> case somethingBadHappened
> }
>
>
> enum Result {
> case success(T)
> case failure(Swift.Error)
>
> init(throwingClosure: (Void) throws -> T) {
> do {
> self = try .success(throwingClosure())
> } catch {
> self = .failure(error)
> }
> }
> }
>
> func burnItDown() throws -> Void {
> throw UselessError.somethingBadHappened
> }
>
> Result(throwingClosure: burnItDown)
> ```
>
>
>
> On Mon, Jan 9, 2017 at 10:28 PM, Jacob Bandes-Storch via swift-users <
> swift-users@swift.org> wrote:
>
> Moving to swift-users list.
>
> No, there's no way to do this today. The point of rethrows is that within
> one call site, "f(block)" can be treated as throwing if the block throws,
> or not throwing if the block doesn't throw. In your example, once the
> FStore object is constructed, the information about the original passed-in
> function is lost, so the caller has no way to know whether call() can throw
> or not.
>
> If this *were* possible, the information would somehow need to be encoded
> in the type system when creating FStore(f: block). That would require
> something like dependent typing, or generic-param-based-rethrows, e.g.
>
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function
> depends on throws-ness of T
> }
>
>
>
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <
> swift-evolut...@swift.org> wrote:
>
> Hi,
>
> If I have an escaping function that I store and then call, I need to
> declare the calling function as throwing, not rethrowing. EG:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have
> to use throws
> }
> Is there a better solution?
>
> Thanks for any suggestions,
>
>   -- Howard.
>
>
>
>
>
> ___
>
>
> swift-evolution mailing list
>
>
> swift-evolut...@swift.org
>
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>
>
> ___
>
>
> swift-users mailing list
>
>
> swift-users@swift.org
>
>
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
>
>
>
>
> --
-- Howard.
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-11 Thread Howard Lovatt via swift-users
Another possibility, other than generics, would be to drop rethrows all
together and have the compiler infer if a throw is possible or not,
including:

struct FStore {
let f: () throws -> Void
func call() throws { try f() }
}

The compiler can make two versions, one if f can throw and one if it
definitely doesn't.

Just a thought.

On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch 
wrote:

> Moving to swift-users list.
>
> No, there's no way to do this today. The point of rethrows is that within
> one call site, "f(block)" can be treated as throwing if the block throws,
> or not throwing if the block doesn't throw. In your example, once the
> FStore object is constructed, the information about the original passed-in
> function is lost, so the caller has no way to know whether call() can throw
> or not.
>
> If this *were* possible, the information would somehow need to be encoded
> in the type system when creating FStore(f: block). That would require
> something like dependent typing, or generic-param-based-rethrows, e.g.
>
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function
> depends on throws-ness of T
> }
>
>
>
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <
> swift-evolut...@swift.org> wrote:
>
> Hi,
>
> If I have an escaping function that I store and then call, I need to
> declare the calling function as throwing, not rethrowing. EG:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have
> to use throws
> }
> Is there a better solution?
>
> Thanks for any suggestions,
>
>   -- Howard.
>
>
>
>
>
> ___
>
>
> swift-evolution mailing list
>
>
> swift-evolut...@swift.org
>
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
>
>
> --
-- Howard.
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-10 Thread T.J. Usiyan via swift-users
I suggest using an enum to represent success and failure. It's usually
referred to as `Result`. It might seem weird for the closure that you
presented as an example, since it would be Result, but it properly
captures the possibility of having thrown.

``` swift
enum UselessError : Swift.Error {
case somethingBadHappened
}


enum Result {
case success(T)
case failure(Swift.Error)

init(throwingClosure: (Void) throws -> T) {
do {
self = try .success(throwingClosure())
} catch {
self = .failure(error)
}
}
}

func burnItDown() throws -> Void {
throw UselessError.somethingBadHappened
}

Result(throwingClosure: burnItDown)
```



On Mon, Jan 9, 2017 at 10:28 PM, Jacob Bandes-Storch via swift-users <
swift-users@swift.org> wrote:

> Moving to swift-users list.
>
> No, there's no way to do this today. The point of rethrows is that within
> one call site, "f(block)" can be treated as throwing if the block throws,
> or not throwing if the block doesn't throw. In your example, once the
> FStore object is constructed, the information about the original passed-in
> function is lost, so the caller has no way to know whether call() can throw
> or not.
>
> If this *were* possible, the information would somehow need to be encoded
> in the type system when creating FStore(f: block). That would require
> something like dependent typing, or generic-param-based-rethrows, e.g.
>
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function
> depends on throws-ness of T
> }
>
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <
> swift-evolut...@swift.org> wrote:
>
>> Hi,
>>
>> If I have an escaping function that I store and then call, I need to
>> declare the calling function as throwing, not rethrowing. EG:
>>
>> struct FStore {
>> let f: () throws -> Void
>> init(f: @escaping () throws -> Void) { self.f = f }
>> func call() throws { try f() } // Can't put rethrows here - have
>> to use throws
>> }
>> Is there a better solution?
>>
>> Thanks for any suggestions,
>>
>>   -- Howard.
>>
>> ___
>> swift-evolution mailing list
>> swift-evolut...@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] [swift-evolution] Best way to handle escaping function that might throw

2017-01-09 Thread Jacob Bandes-Storch via swift-users
Moving to swift-users list.

No, there's no way to do this today. The point of rethrows is that within
one call site, "f(block)" can be treated as throwing if the block throws,
or not throwing if the block doesn't throw. In your example, once the
FStore object is constructed, the information about the original passed-in
function is lost, so the caller has no way to know whether call() can throw
or not.

If this *were* possible, the information would somehow need to be encoded
in the type system when creating FStore(f: block). That would require
something like dependent typing, or generic-param-based-rethrows, e.g.

struct FStore Void> {  // made-up syntax
let f: T
func call() rethrows(T) { try f() }  // throws-ness of this function
depends on throws-ness of T
}

On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <
swift-evolut...@swift.org> wrote:

> Hi,
>
> If I have an escaping function that I store and then call, I need to
> declare the calling function as throwing, not rethrowing. EG:
>
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have
> to use throws
> }
> Is there a better solution?
>
> Thanks for any suggestions,
>
>   -- Howard.
>
> ___
> swift-evolution mailing list
> swift-evolut...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users