[swift-evolution] [Preemptive Proposal] Operator for Lenses
Brent Royal-Gordon
brent at architechies.com
Thu Jan 14 19:30:16 CST 2016
> Could you please explain what a lens is/means? I only found [1], but quick skimming didn't reveal any lenses.
>
> [1] https://www.youtube.com/watch?v=estNbh2TF3E
In pure functional programming languages, where you can't mutate existing instances, a lens is a function which takes an instance and a new value for some field inside the instance—sometimes deep inside it—and returns a copy of the original instance with that new value in place. So, for instance, if you have a `User` type which has a `name` property:
let nameLens = User.name
let currentName = nameLens.get(originalUser) // get the name from originalUser
let modifiedUser = nameLens.set(originalUser, to: "Joe") // return a copy of originalUser with name set to "Joe"
In functional programming, you can easily chain lenses together, so that you could create a lens for, say, `User.creditCards[0].billingAddress.houseNumber`—and the setter on that lens will actually take a house number and return a whole different `User` instance with that house number applied.
Now, Swift is a little different from a pure functional language. It doesn't have the limitation that functional languages do—it's perfectly fine to modify existing instances—so a Swift lens's setter would probably actually modify the existing instance. On the other hand, Swift often modifies an existing value inside a property instead of creating a whole new one, so the "setter" is better modeled as a read-modify-write operation:
let nameLens = User.name
let currentName = nameLens.get(originalUser)
nameLens.modify(originalUser) { (inout name: String) in
name = "Joe"
}
Finally, there's the question of how you should *access* a lens. `User.name`—that is, a lens that can be used with any instance of `User`—is good for some things, but you'd also like to be able to get a lens that's already bound to a particular instance.
Michael Henson is basically proposing syntaxes to retrieve a lens for a particular instance, but personally, I think this is putting the cart before the horse a bit. Right now, I'm personally more interested in finding out what a lens *is* in Swift. What can it do? How is it expressed? What can you use it for?
--
Brent Royal-Gordon
Architechies
More information about the swift-evolution
mailing list