The Swift Evolution forums are full of exciting pitches and proposals for new functionality in Swift and it’s ecosystem.
After the sunsetting of the Swift Weekly Brief I’ve been missing a digest of news from SE.
I will be no means try to replace the Swift Weekly Brief - since I don’t have the bandwidth for such an undertaking - but I’ll try to present a few of the pitches and proposals that I find interesting.
swift-evolution/0380-if-switch-expressions.md at main · apple/swift-evolution · GitHub
https://forums.swift.org/t/se-0380-if-and-switch-expressions/61899
As the title suggests, this proposal adds support for using if- and switch-statements as expressions under certain circumstances.
From the proposal:
- Returning values from functions, properties, and closures;
- Assigning values to variables; and
- Declaring variables.
Furthermore the following criteria must be satisfied:
Each branch of the if, or each case of the switch, must be a single expression.
One of the things I love most about Swift is it's readability. But I do not think that readability suggests verbosity. In many cases I find that terseness improves on readability.
One example of this is the if let
shorthand introduced with Swift 5.7 from SE-0345 by Cal Stephens. I honestly thought that this functionality was a bit unnecessary, but after it's release I have come to love it. It avoids duplication of labels that did not really add anything to the readability. You need to know of this new syntax, but I find that it's so natural that when you read it, you'll know what it's about.
A very common pattern in the code bases I work with is mapping enums. We have many, many examples of mapping enums to localizable strings, mapping enums to colors and mapping enums to other enums.
In most of these cases the mapping is split into a function or a calculated property, so that it basically looks like this:
extension InvoiceMode {
var buttonTitle: String {
switch self {
case .creditNote:
return L10n.InvoicePayment.sendCreditNote
case .invoice:
return L10n.InvoicePayment.sendInvoice
}
}
}
or
extension MenuItem {
var localizedTitle: String {
switch self {
case .customerLookup: return L10n.Menu.customerLookup
case .customerSignup: return L10n.Menu.customerSignup
case .addBasketComment: return L10n.Menu.comment
case .addBasketDiscount: return L10n.Menu.addBasketDiscount
...
}
}
In all of these mappings I have always felt that the repeated return
statements didn't add to the readability at all.
I can see from the switch statement inside a function body that I am mapping from one domain to another - and all I care about is the source and destination values.
SE-0380 exactly allows us to skip the return statements in these situations, so that the above becomes:
extension InvoiceMode {
var buttonTitle: String {
switch self {
case .creditNote:
L10n.InvoicePayment.sendCreditNote
case .invoice:
L10n.InvoicePayment.sendInvoice
}
}
}
or
extension MenuItem {
var localizedTitle: String {
switch self {
case .customerLookup: L10n.Menu.customerLookup
case .customerSignup: L10n.Menu.customerSignup
case .addBasketComment: L10n.Menu.comment
case .addBasketDiscount: L10n.Menu.addBasketDiscount
...
}
}
I just love being able to skip the extra ceremony here and focus on mapping. :-)
I don't think that I will be using if
expressions quite as much as switch
expressions, but I suspect that I would be using it within closures, function bodies and properties like in the examples above.
Both statements can also be used as expressions when declaring variables and assigning to variables. I do think that I will use those a bit less, but they definitely have their uses.
From the proposal:
let bullet = if isRoot && (count == 0 || !willExpand) { "" } else if count == 0 { "- " } else if maxDepth <= 0 { "▹ " } else { "▿ " }
Please have a look at the proposal itself - and at the discussion topic on the SE forums for more details.