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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to