[swift-evolution] [Proposal]: Escaping another (unused) scope pyramide with 'guard try catch'

Erica Sadun erica at ericasadun.com
Fri Feb 5 12:57:36 CST 2016


I am having problems trying to understand why you'd want to circumvent the throwing chain and perform error handling and recovery late in the call tree rather than at the root point that initiated the request.  

-- Erica


> On Feb 5, 2016, at 10:54 AM, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hello dear Swift community,
> 
> this proposal might seem like some new syntax sugar, but it also aims to escape the 'do { }' scope from the 'do try catch‘ mechanism while making the existing error handling more powerful.
> 
> Lets assume we have some sort of network type, which can throw a ton of different errors:
> 
> struct TCPListener {
> 	
> 	init(address: String) throws { /* implement */ }
> 
> 	func accept() throws -> TCPConn { /* implement */ }
> 
> 	/* ... */
> }
> 
> A way of implimentation might look like this:
> 
> let listener: TCPListener
> do {
> 	listener = try TCPListener("some valid address")
> 
> 	// we could do more work here, but if we need to catch more
> 	// errors we will result in a new PYRAMIDE OF DOOM
> } catch {
> 	fatalError()
> }
> 
> At this point think about the comment inside the 'do { }' scope. Such an application might result in a new pyramide of doom as we know from optional unwrapping before 'guard else' mechanism was introduced.
> 
> let clientConn: TCPConn
> do {
> 	clientConn = try listener.accept() // save to call accept method
> } catch {
> 	fatalError()
> } 
> 
> As you can see this application might not need the extra 'do' scope at all, and if it does, the 'do try catch' is still there.
> 
> I propose a new error handling mechanism that mimics the solution for optional pyramide of doom, which adds a slightly better syntax and removes the unneeded/unused 'do { }' scope (as for the example from above). Not only can this mechanism guarantee the execution of a throwing function without any errors (like a true guard condition) it also can assign returned values to a new constant/variable.
> 
> Introducing the 'guard try catch' mechanism:
> 
> guard try throwingFunc() catch { 
> 	/* handle error */ 
> }
> 
> guard try throwingFunc() catch _ { 
> 	/* handle error */ 
> }
> 
> guard try throwingFunc() catch pattern { 
> 	/* handle error */ 
> }
> 
> guard try throwingFunc() catch pattern where condition { 
> 	/* handle error */ 
> }
> 
> guard let newInstance = try throwingFuncReturns() catch ... { 
> 	/* handle error */ 
> }
> 
> Where '...' represents the different combinations of possible patterns already showed in the first 4 examples.
> 
> We also might want the return type to be mutable.
> 
> guard var newMutableInstance = try throwingFuncReturns() catch ... { 
> 	/* handle error */ 
> }
> 
> This mechanism also makes the error handling more powerful, since it can catch more specific errors defined with 'where condition'.
> 
> Lets rebuild the example from above with the new mechanism:
> 
> guard let listener = try TCPListener("some valid address") catch {
> 	fatalError()
> }
> 
> guard let clientConn = try listener.accept() catch {
> 	fatalError()
> } 
> 
> One think that should be mentioned here is that the method call from the second 'guard' is safe, because a 'guard' body may not fall through.
> 
> Impact on existing codebase: None, because the mechanism is new and does not break any existing code.
> 
> I'm really curious about your opinions.
> _______________________________________________
> 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-evolution/attachments/20160205/d3a0b813/attachment.html>


More information about the swift-evolution mailing list