[swift-evolution] More flexible guard statement

Arthur Ariel Sabintsev arthur at sabintsev.com
Wed Dec 16 22:19:56 CST 2015


Hi Adrian,

Yes, as noted by others in a separate response, I misunderstood the
question. Like you, I still don't see a problem, as the OP is trying to
achieve something that can already be done (see one of my previous posts in
this thread).

On Wed, Dec 16, 2015 at 4:07 AM Adrian Kashivskyy via swift-evolution <
swift-evolution at swift.org> wrote:

> Arthur,
>
> There’s a parallel thread going on right now about adding unless/until
> into the stdlib. I think that’s what you may want.
>
>
> `guard` cannot be compared to `if` or `unless` because it's used as an
> assertion with an early exit, not a condition. Consider the following:
>
> let x: Int? = 5
>
> guard let x = x where 1...10 ~= x else {
> return
> }
>
> // x is unwrapped and between 1 and 10
>
> print(x)
>
>
> Compare this to `unless`:
>
> unless let x = x where 1...10 ~= x {
> // x is unwrapped and between 1 and 10
> print(x)
> } else {
> return
> }
>
>
> As you can see, `unless` introduces two new scopes and leads to creation
> of an indentation, which can result in a pyramid of doom. In addition,
> `guard` requires you to early exit the scope using `return` or `break`,
> which is not the case when using `unless`.
>
> That being said, I don't fully understand the original problem, because
> this is possible:
>
> guard
> let col = tableView?.columnWithIdentifier("MyColumn"),
> let headerCell
> = tableView?.tableColumns[0].headerCell as? MyTableHeaderCell
>
>
> where col != -1
> else {
> NSBeep()
>
> print("an error occurred")
>
> return
>
> }
>
>
>
> Pozdrawiam – Regards,
> Adrian Kashivskyy
>
> Wiadomość napisana przez Jeff Kelley via swift-evolution <
> swift-evolution at swift.org> w dniu 14.12.2015, o godz. 03:45:
>
>
> The first line of your example would need to use self.tableView, which is
> optional, so col would be optional as well. The assignment happens after
> the unwrap.
>
> I find this a lot in my code where I need to chain together a string of
> optional unwrapping and assignment from those optionals, like so:
>
> if let foo = foo, bar = foo.bar, baz =foo.baz {
>
> }
>
>
> In that case, if bar is a non-optional property of foo, I need to rewrite
> it like this:
>
> if let foo = foo, baz = foo.baz {
> let bar = foo.bar
>
> }
>
>
> These examples aren’t too bad, but as you add more layers of unwrapping,
> it gets more difficult to do without multiple levels of indentation—though
> this is probably more a code smell than anything else.
>
>
> Jeff Kelley
>
> SlaunchaMan at gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> |
> jeffkelley.org
>
> On Dec 12, 2015, at 3:58 PM, Zef Houssney via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Jacob, you actually don’t need to have the redundant guard statement. If
> you want to assign something to a constant or variable, you just do that
> before the `guard let`, and you can still use it in the `where`:
>
> let col = tableView.columnWithIdentifier("MyColumn")
> guard let tableView = self.tableView where col != -1 else {
>  NSBeep()
>  print("an error occurred")
>  return
> }
>
> Zef
>
>
>
> On Dec 12, 2015, at 11:23 AM, Al Skipp via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> How about extending ‘NSTableView’ with a subscript?
>
> extension NSTableView {
> subscript(columnID columnID: String) -> Int? {
>   get {
>     let c = columnWithIdentifier(columnID)
>     return c >= 0 ? c : .None
>   }
> }
> }
>
> tableView[columnID: "MyColumn"]
>
>
> It doesn’t address the general case, but it does introduce a more Swifty
> way of dealing with non-existent return values in this use case and would
> enable you to use it with guard.
>
> Al
>
> On 12 Dec 2015, at 17:43, Jakob Egger via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> At the moment "guard let" can only be used for unwrapping optionals. It
> would be really nice if it could also be used with non-optional values.
> For example, I'd like to write code like the following
>
> guard
>  let tableView = self.tableView,
>  let col = tableView.columnWithIdentifier("MyColumn") where col != -1
> else {
>  NSBeep()
>  print("an error occurred")
>  return
> }
>
> This is not possible, because the second let assignment is non-optional,
> so I have to write it like this:
>
> guard let tableView = self.tableView else {
>  NSBeep()
>  print("an error occurred")
>  return
> }
> let col = tableView.columnWithIdentifier("MyColumn")
> guard col != -1 else {
>  NSBeep()
>  print("an error occurred")
>  return
> }
>
> This leads to a lot of duplicated error handling code.
>
> Ideally, I'd also like to mix let & where clauses in a single guard
> statement, like this:
>
> guard
>  let tableView = self.tableView,
>  let col = tableView.columnWithIdentifier("MyColumn") where col !=
>  -1,
>  let headerCell = tableView.tableColumns[col].headerCell as?
>  MyTableHeaderCell
> else {
>  NSBeep()
>  print("an error occurred")
>  return
> }
>
> What do you think? Right now I always end up writing a lot of separate
> guard statement, and I have a lot of repeated error handling code.
>
>
> Best regards,
> Jakob
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-- 
Best,

Arthur / Sabintsev.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151217/a6c7befa/attachment.html>


More information about the swift-evolution mailing list