Extension methods for non-nominal types

If you can tolerate a postfix operator like eg , then you can extend (an "invisible" wrapper of) any type and write eg:

let myView = UIView()•.configure {
    $0.translatesAutoresizingMaskIntoConstraints = false
    $0.backgroundColor = UIColor(red: 1, green: 0, blue: 0.2, alpha: 0.4)
}
Here's the code that will make that work.
struct NominalWrapper<InnerSelf> {
    let innerSelf: InnerSelf
    init(_ innerSelf: InnerSelf) { self.innerSelf = innerSelf }
}

postfix operator •
postfix func •<T>(lhs: T) -> NominalWrapper<T> { return NominalWrapper(lhs) }

extension NominalWrapper where InnerSelf: AnyObject {
    func configure(_ block: (InnerSelf) -> Void) -> InnerSelf {
        block(innerSelf)
        return innerSelf
    }
}

I guess the same concept could be taken further, to allow:

(1, 2)•
    .scaled(by: (3, 4))•
    .translated(by: (-3, -8))•
    .isAtOrigo()
    .print() // Prints true

or

(1, 2)• * (3, 4)• - (3, 8)• == (0, 0)• // true

or whatever (note that (1, 2)• is of a type that can conform to protocols etc, unlike (1, 2)).

EDIT: But playing around with this will probably mean running into this and other tuple related compiler bugs.

1 Like