Idea brought up on Swift Evolution by Zsolt Szatmari:
The only thing I am really missing right now from Swift is described as following. This works in some other languages, e.g. F#, Kotlin, and Haskell.
let john = {firstName="John"; lastName="Doe"}
let alice = {john with FirstName="Alice"}
Current way to do this in Swift is:let john = (firstName:"John", lastName:"Doe")
var alice = john
alice.firstName = "Alice"
This might seem to be a nuance, but it’s more cumbersome (especially if one wants to do this frequently), and we are left with a var at the end. Also, this idea rhymes with the current direction of removing var arguments from functions.
Unless I am overlooking something major here (wouldn’t be the first time), there’s actually a pretty easy way to do this in existing Swift:
struct Person { var firstName, lastName: String } let john = Person(firstName: "John", lastName: "Doe") func modify(item: T, update: (inout T) -> Void) -> T { var this = item update(&this) return this } let carol: Person = modify(john) { $0.firstName = "Carol" } print(carol) // Person(firstName: "Carol", lastName: "Doe")
The `modify()` function makes a new copy, applies any changes, and returns the new instance. Swift’s type inference system ensures that the associated closure can access instance members.
One Comment
Lenses are another solution to this problem:
http://chris.eidhof.nl/posts/lenses-in-swift.html
https://m.youtube.com/watch?v=ofjehH9f-CU