On Wed, Jul 13, 2016 at 1:14 PM, Tim Vermeulen via swift-evolution < swift-evolution@swift.org> wrote:
On 13 Jul 2016, at 17:47, Charlie Monroe <charlie@charliemonroe.net> > wrote:
Hi Tim,
the core team asked us to defer any discussion on post-Swift-3 related
proposals.
That said, there have been several discussion around this topic (in the
past few months) and I believe the general attitude towards them was
negative, due to it leading to statements such as
guard <condition> else { }
which
a) doesn't express what will happen when the condition is not met, making
the code hard to read
b) can lead to bugs in code since the compiler makes sure that the flow
doesn't continue beyond the guard statement and with default returns, this
would compiler without a warning or an error:
for obj in array {
guard obj.meetsConditions() else {
// Implicit return - most likely not intentional,
// you most likely want "continue" in here
}
// ...
}
On Jul 13, 2016, at 4:57 PM, Tim Vermeulen via swift-evolution < > swift-evolution@swift.org> wrote:
This idea is purely additive and isn’t to be considered for Swift 3.
Oftentimes a function has a very obvious default argument to fall back on.
If the return value is optional, this is generally nil. If the return value
is Bool, it’s probably `false`. Often this fallback value is returned at
the end of the function, just to return something if nothing has been
returned yet. For instance, consider this TreeNode class:
class TreeNode<Element> {
var value: Element
var children: [TreeNode]
init(value: Element) {
self.value = value
children =
}
func contains(_ predicate: (Element) throws -> Bool) rethrows -> Bool
{
if try predicate(value) {
return true
}
for child in children {
if try child.contains(predicate) {
return true
}
}
return false // 1
}
func first(where predicate: (Element) throws -> Bool) rethrows ->
Element? {
if try predicate(value) {
return value
}
for child in children {
if let result = try child.first(where: predicate) {
return result
}
}
return nil // 2
}
var leftMostDescendant: TreeNode? {
if let child = children.first {
return child.leftMostDescendant ?? child
}
return nil // 3
}
}
These code patterns are quite usual. If we could give default return
values to functions, we could get rid of the final `return` statements:
func contains(_ predicate: (Element) throws -> Bool) rethrows -> Bool =
false {
if try predicate(value) {
return true
}
for child in children {
if try child.contains(predicate) {
return true
}
}
}
func first(where predicate: (Element) throws -> Bool) rethrows -> Element?
= nil {
if try predicate(value) {
return value
}
for child in children {
if let result = try child.first(where: predicate) {
return result
}
}
}
var leftMostDescendant: TreeNode? = nil {
if let child = children.first {
return child.leftMostDescendant ?? child
}
}
The default return value shouldn’t be part of the function signature (i.e.
it shouldn’t appear in interface files) because it’s an implementation
detail, but right after the return type is probably the most natural place
to put it (similar to default function parameters).
Let me know what you think.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution