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

Slava Pestov spestov at apple.com
Thu Jan 12 17:42:45 CST 2017


> On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution <swift-evolution at 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 <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> 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<T: () throws -> 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-evolution at swift.org <mailto:swift-evolution at 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-evolution at swift.org <mailto:swift-evolution at swift.org>
> 
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> 
> 
> 
> 
> -- 
> -- Howard.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170112/615f78b3/attachment.html>


More information about the swift-users mailing list