Lenses into Swift properties
Asked Answered
P

2

8

Is there some way to automatically generate a getter/setter function pair for a property in a class in Swift? Something along the lines of a lens in Haskell.

I've been able to do the following manually:

class PropertyLens<U, T> {
    let getter: U -> T
    let setter: (U, T) -> ()

    init(getter: (U -> T), setter: ((U, T) -> ())) {
        self.getter = getter
        self.setter = setter
    }

    func get(u: U) -> T {
        return getter(u)
    }

    func set(u: U, t: T) {
        setter(u, t)
    }
}
// ...
let myPropertyLens = PropertyLens<MyClass, Int>(getter: { $0.myProperty }, setter: { $0.myProperty = $1 })

However, that becomes verbose, tedious, and more error-prone than I'd like. Is there a built-in feature I'm missing?

Pembroke answered 22/10, 2014 at 20:58 Comment(6)
What's your goal? As much as I understand them, lenses in Haskell are designed to allow for mutable state, which Swift includes already. Between the willSet and didSet handlers and computed properties, there's a lot of flexibility.Overslaugh
My goal is to be able to pass this lens into another object to manipulate the properties. In my current project, it's an object that generates table view cells and responds to presses in a standard way. Lenses in Haskell aren't about mutable state as much as they're about providing a composable way to query and manipulate data structures, though the illusion of mutability emerges from them.Pembroke
ObjC way will be just pass a string keypath but you don't have type safetyAcidulant
What do U & T stand for? Side-note: You'll find that single-letter variable or type names are rare and discouraged in Swift; it make code much more readable to any Swift programmer if the each identifier is at least one word concisely describing its purpose.Isodynamic
Swift now have KeyPath and WritableKeyPath, which are native-supported lensPickford
@NateCook lenses can be combined to create powerful getter & setter to manipulate deep nested data structures. KeyPath and computed properties cannot be combined. KeyPaths are simplified lenses, lenses are superpowered KeyPathsPickford
C
0

For the answer itself, so far (1.1) no language construct will substitute what you are doing (wrapping the access process of a stored property into a referenciable object).

For the opinion part of the answer, it looks like your code only works with public variables, which are nasty for they break basic encapsulation rules, is that correct?

Coomer answered 4/12, 2014 at 18:35 Comment(0)
S
0

You should give Sourcery a try. I have the same problem and I run into this tool, if you make a quick search you should easily find some already made templates for Sourcery that lets you generate lenses for your data types.

Stays answered 14/5, 2019 at 18:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.