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

> On Dec 19, 2016, at 1:47 PM, Derrick Ho <[email protected]> wrote:
> 
> That is correct Andy. Let-constant can not be assigned a new value after it 
> gets its initial value.
> 
> It is unclear why you are against turning your properties into var's.  
> Because you are using structs, all properties are copied by value.
> 
> struct Person {
>   var name: String
> }
> 
> let andy = Person(name: "Andy")
> var brandon = andy; brandon.name <http://brandon.name/> = "Brandon"
> 
> andy.name <http://andy.name/> // "Andy"
> brandon.name <http://brandon.name/> // "Brandon"
> 
> I believe this accomplishes the same thing you wanted in with(name:)
> 
> On Mon, Dec 19, 2016 at 1:26 PM Andy Chou via swift-evolution 
> <[email protected] <mailto:[email protected]>> wrote:
> Thanks Erica, I wasn't aware of that Swift evolution proposal. If I'm reading 
> it right, this wouldn't work with structs with let-variables...?  Here's what 
> I get with this example:
> 
> struct Person {
>     let name: String
>     let address: String
> }
> 
> @discardableResult
> public func with<T>(_ item: T, update: (inout T) throws -> Void) rethrows -> 
> T {
>     var this = item
>     try update(&this)
>     return this
> }
> 
> let john = Person(name: "John", address: "1 battery st")
> let jane: Person = with(john) { $0.name <http://0.name/> = "Jane" }     // 
> Test.swift:24:41: Cannot assign to property: 'name' is a 'let' constant
> 
> Andy
> 
> 
>> On Dec 19, 2016, at 11:44 AM, Erica Sadun <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> https://github.com/apple/swift-evolution/pull/346 
>> <https://github.com/apple/swift-evolution/pull/346>
>> 
>> Be aware that there's a bug that's being worked on:
>> 
>> https://bugs.swift.org/browse/SR-2773 <https://bugs.swift.org/browse/SR-2773>
>> 
>> -- E
>> 
>> 
>>> On Dec 19, 2016, at 12:40 PM, Andy Chou via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Of course. Thanks for pointing out the obvious solution. This preserves the 
>>> immutability of the struct and doesn't require O(n^2) code for structs with 
>>> large numbers of fields. 
>>> 
>>> I was thinking of a generic solution - perhaps something like a synthetic 
>>> initializer that does what your solution does. But that may be overkill 
>>> given how relatively easy it is to do this per struct...
>>> 
>>> On the other hand a generic solution would encourage using immutable 
>>> structs. I wasted too much time trying to solve this, I suspect others 
>>> would just give up and use var, or even classes. 
>>> 
>>> Andy
>>> 
>>> On Dec 19, 2016, at 10:43 AM, Nick Keets <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> You are probably asking for a generic solution, but for a specific struct 
>>>> you can implement it like this:
>>>> 
>>>> 
>>>> 
>>>> 
>>>> extension Person {
>>>>     func with(name: String? = nil, address: String? = nil, phone: String? 
>>>> = nil) -> Person {
>>>>         let name = name ?? self.name
>>>>         let address = address ?? self.address
>>>>         let phone = phone ?? self.phone
>>>>         return Person(name: name, address: address, phone: phone)
>>>>     }
>>>> }
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>>, wrote:
>>>> 
>>>> 
>>>>> I like that structs are value types in Swift, this encourages the use of 
>>>>> immutable data. O'Caml has an operator "with" that allows for copying an 
>>>>> existing struct with a change to one field. I looked at Lenses for this 
>>>>> functionality and it seems like a lot to digest for something so simple. 
>>>>> I also tried to implement this using a constructor, or a function, and it 
>>>>> was not obvious how to do so without a lot of code duplication.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> What's I'm looking for is something like this (not necessarily with this 
>>>>> syntax):
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> struct Person {
>>>>> 
>>>>> 
>>>>> let name: String
>>>>> 
>>>>> 
>>>>> let address: String
>>>>> 
>>>>> 
>>>>> let phone: String
>>>>> 
>>>>> 
>>>>> }
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> func f() {
>>>>> 
>>>>> 
>>>>> let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, 
>>>>> CA", phone: "1234567")
>>>>> 
>>>>> 
>>>>> let chris = andy.with(name: "Chris")
>>>>> 
>>>>> 
>>>>> let dave = andy.with(address: "50 Townsend St., San Francisco, CA")
>>>>> 
>>>>> 
>>>>> }
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> I tried to implement a "with" function like this but default arguments 
>>>>> cannot reference properties of self. Same problem trying to do this in a 
>>>>> constructor.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> Obviously it's possible to create an entirely new Person specifying the 
>>>>> values from an existing Person, but this is very tedious with structures 
>>>>> with many properties.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> Anyone taken a look at this before? Any suggestions?
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> Andy
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> 
>>>>> 
>>>>> swift-evolution mailing list
>>>>> 
>>>>> 
>>>>> [email protected] <mailto:[email protected]>
>>>>> 
>>>>> 
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> 
> _______________________________________________
> 
> 
> swift-evolution mailing list
> 
> 
> [email protected] <mailto:[email protected]>
> 
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to