<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">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.</div><div class=""><br class=""></div><div class="">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 :)</div><div class=""><br class=""></div><div class="">Andy</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 19, 2016, at 1:47 PM, Derrick Ho &lt;<a href="mailto:wh1pch81n@gmail.com" class="">wh1pch81n@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><div class="gmail_msg"><div class="gmail_msg">That is correct Andy.  Let-constant can not be assigned a new value after it gets its initial value.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It is unclear why you are against turning your properties into var's.&nbsp; Because you are using structs, all properties are copied by value.</div></div></div><div class=""><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">struct Person {</div><div class="gmail_msg"><span style="color:rgb(49,49,49);word-spacing:1px;background-color:rgb(255,255,255)" class="">&nbsp; var name: String</span><br class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">}</div><div class="gmail_msg"><br class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px;background-color:rgb(255,255,255)" class="">let andy = Person(name: "Andy")</span><br class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><span style="color:rgb(49,49,49);word-spacing:1px;background-color:rgb(255,255,255)" class="">var brandon = andy; <a href="http://brandon.name/" class="">brandon.name</a> = "Brandon"</span><br class="gmail_msg"></div><div class="gmail_msg"><span style="color:rgb(49,49,49);word-spacing:1px;background-color:rgb(255,255,255)" class=""><br class=""></span></div><div class="gmail_msg"><span style="color:rgb(49,49,49);word-spacing:1px;background-color:rgb(255,255,255)" class=""><a href="http://andy.name/" class="">andy.name</a> // "Andy"</span></div><div class="gmail_msg"><font color="#313131" class=""><span style="word-spacing:1px;background-color:rgb(255,255,255)" class=""><a href="http://brandon.name/" class="">brandon.name</a> // "Brandon"</span></font></div><div class="gmail_msg"><font color="#313131" class=""><span style="word-spacing:1px;background-color:rgb(255,255,255)" class=""><br class=""></span></font></div><div class="gmail_msg"><font color="#313131" class=""><span style="word-spacing:1px;background-color:rgb(255,255,255)" class="">I believe this accomplishes the same thing you wanted in with(name:)</span></font></div><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">On Mon, Dec 19, 2016 at 1:26 PM Andy Chou via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">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...?&nbsp; Here's what I get with this example:<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">struct&nbsp;Person {<br class="gmail_msg">&nbsp; &nbsp;&nbsp;let&nbsp;name:&nbsp;String<br class="gmail_msg">&nbsp; &nbsp;&nbsp;let&nbsp;address:&nbsp;String<br class="gmail_msg">}<br class="gmail_msg"><br class="gmail_msg"></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">@discardableResult<br class="gmail_msg">public&nbsp;func&nbsp;with&lt;T&gt;(_&nbsp;item:&nbsp;T, update: (inout&nbsp;T)&nbsp;throws&nbsp;-&gt;&nbsp;Void)&nbsp;rethrows&nbsp;-&gt;&nbsp;T&nbsp;{<br class="gmail_msg">&nbsp; &nbsp;&nbsp;var&nbsp;this = item<br class="gmail_msg">&nbsp; &nbsp;&nbsp;try&nbsp;update(&amp;this)<br class="gmail_msg">&nbsp; &nbsp;&nbsp;return&nbsp;this<br class="gmail_msg">}<br class="gmail_msg"><br class="gmail_msg">let&nbsp;john =&nbsp;Person(name:&nbsp;"John", address:&nbsp;"1 battery st")<br class="gmail_msg">let&nbsp;jane:&nbsp;Person&nbsp;=&nbsp;with(john) { $<a href="http://0.name/" class="gmail_msg" target="_blank">0.name</a> =&nbsp;"Jane"&nbsp;} &nbsp; &nbsp; // Test.swift:24:41: Cannot assign to property: 'name' is a 'let' constant</div><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"></div></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">Andy</div></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Dec 19, 2016, at 11:44 AM, Erica Sadun &lt;<a href="mailto:erica@ericasadun.com" class="gmail_msg" target="_blank">erica@ericasadun.com</a>&gt; wrote:</div><br class="gmail_msg m_3914830742118468873m_-7663707755917583867m_6095329424735225132Apple-interchange-newline"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><a href="https://github.com/apple/swift-evolution/pull/346" class="gmail_msg" target="_blank">https://github.com/apple/swift-evolution/pull/346</a></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Be aware that there's a bug that's being worked on:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><a href="https://bugs.swift.org/browse/SR-2773" class="gmail_msg" target="_blank">https://bugs.swift.org/browse/SR-2773</a></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">-- E</div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Dec 19, 2016, at 12:40 PM, Andy Chou via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail_msg m_3914830742118468873m_-7663707755917583867m_6095329424735225132Apple-interchange-newline"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">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.&nbsp;</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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...</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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.&nbsp;</div><div class="gmail_msg"><br class="gmail_msg">Andy</div><div class="gmail_msg"><br class="gmail_msg">On Dec 19, 2016, at 10:43 AM, Nick Keets &lt;<a href="mailto:nick.keets@gmail.com" class="gmail_msg" target="_blank">nick.keets@gmail.com</a>&gt; wrote:<br class="gmail_msg"><br class="gmail_msg"></div><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><div name="messageBodySection" class="gmail_msg">You are probably asking for a generic solution, but for a specific struct you can implement it like this:<br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><div style="margin:0px;line-height:normal;font-family:Menlo;color:rgb(186,45,162)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">extension</span> <span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Person</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">{</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">func</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">with(name:</span> <span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">String</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? =</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">nil</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, address:</span> <span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">String</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? =</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">nil</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, phone:</span> <span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">String</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? =</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">nil</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) -&gt;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Person</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">{</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">name = name ??</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">self</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">name</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">address = address ??</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">self</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">address</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">let</span> <span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">phone = phone ??</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">self</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">phone</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:#ba2da2" class="gmail_msg">return</span> <span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">Person</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(name: name, address: address, phone: phone)</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&nbsp; &nbsp; }</span></div><div style="margin:0px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div><br class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg"></span></div><br class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><br class="gmail_msg"><div name="messageReplySection" class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt;, wrote:<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" style="margin:5px 5px;padding-left:10px;border-left:thin solid #1abc9c" class="gmail_msg">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.<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">What's I'm looking for is something like this (not necessarily with this syntax):<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">struct Person {<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let name: String<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let address: String<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let phone: String<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">}<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">func f() {<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, CA", phone: "1234567")<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let chris = andy.with(name: "Chris")<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">let dave = andy.with(address: "50 Townsend St., San Francisco, CA")<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">}<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">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.<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">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.<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">Anyone taken a look at this before? Any suggestions?<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">Andy<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">_______________________________________________<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></blockquote><br class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"></div></blockquote></div>_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote></div><br class="gmail_msg"></div></div></blockquote></div><br class="gmail_msg"></div></div></div></div></div>_______________________________________________<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"></blockquote></div></div></div></div>
</div></blockquote></div><br class=""></div></body></html>