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.