Good point.

Pierre

> Le 20 déc. 2016 à 11:32, Jeremy Pereira <jeremy.j.pere...@googlemail.com> a 
> écrit :
> 
> 
>> On 20 Dec 2016, at 07:54, Pierre Monod-Broca via swift-evolution 
>> <swift-evolution@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@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@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to