[swift-evolution] "with" operator a la O'Caml?

Jeremy Pereira jeremy.j.pereira at googlemail.com
Tue Dec 20 04:32:19 CST 2016


> On 20 Dec 2016, at 07:54, Pierre Monod-Broca via swift-evolution <swift-evolution at swift.org> wrote:
> 
> But for a struct to be immutable, you don't need all its properties to be let. (I guess that's Derrick's point)

Yes you do. Consider

struct Person: Hashable
{
    let firstName: String
    let lastName: String
    let hashValue: Int

    init(firstName: String, lastName: String)
    {
        self.firstName = firstName
        self.lastName = lastName
        self.hashValue = firstName.hashValue ^ lastName.hashValue
    }
}

func == (l: Person, r: Person) -> Bool
{
    return l.firstName == r.firstName && l.lastName == r.lastName
}

Pretend that the hash value is quite expensive to calculate so I only want to do it once. With the above code, this is fine but if I change the lets to vars (e.g. var firstName: String), I am open to

let chris = Person(firstName: “Chris”, lastName: “Lattner”) // Immutable

var andy = chris
andy.firstName = “Andy”

andy.hashValue // Gives the wrong answer unless you are exceptionally lucky.

I’ve used hashValue, but the same argument would apply to any computed property where you might want to cache the computed value. As soon as you make any of the properties that the computed property depends on `var`, you have to add code that invalidates the cached value which is a performance and a complexity hit for your struct.



> 
> ´´´
> struct Person { /* . . . var properties . . . */ }
> let john = Person() // john is completely immutable
> ´´´
> 
> If a struct has var properties, you can do a mutable copy, change it, assign it to a new let, and you take advantage of immutability again.
> 
> ´´´
> let jim = { var copy = john
>  copy.firstname = "Jim"
>  return copy
> }()
> 
> func with<T>(_ original: T, transform: (inout T) -> ()) -> T {
>  var copy = original
>  transform(&copy)
>  return copy
> }
> 
> let jane = with(john) { $0.firstname = "Jane" }
> // jane is also immutable
> ´´´
> (I didn't check this compiles)
> 
> Pierre
> 
>> Le 19 déc. 2016 à 23:08, Andy Chou via swift-evolution <swift-evolution at swift.org> a écrit :
>> 
>> Value semantics help reduce the issues around mutability, but they don't go away completely. I would like to create structs that are completely immutable after construction. Turning the properties into vars unfortunately loses this idea.
>> 
>> The proposed 'with' function doesn't construct new instances, which means the let constants are already set. Nick's solution works, as it's basically a copy constructor that allows for changes while the new object is constructed. But it needs to be created for each struct. Which I'm fine with :)
>> 
>> Andy
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list