<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="">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=""><br class=""></div><div class="">struct&nbsp;Person {<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;name:&nbsp;String<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;address:&nbsp;String<br class="">}<br class=""><br class="">@discardableResult<br class="">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="">&nbsp; &nbsp;&nbsp;var&nbsp;this = item<br class="">&nbsp; &nbsp;&nbsp;try&nbsp;update(&amp;this)<br class="">&nbsp; &nbsp;&nbsp;return&nbsp;this<br class="">}<br class=""><br class="">let&nbsp;john =&nbsp;Person(name:&nbsp;"John", address:&nbsp;"1 battery st")<br class="">let&nbsp;jane:&nbsp;Person&nbsp;=&nbsp;with(john) { $0.name =&nbsp;"Jane"&nbsp;} &nbsp; &nbsp; // Test.swift:24:41: Cannot assign to property: 'name' is a 'let' constant</div><div class=""><div class=""><div class=""><br class=""></div><div class="">Andy<br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 19, 2016, at 11:44 AM, Erica Sadun &lt;<a href="mailto:erica@ericasadun.com" class="">erica@ericasadun.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><a href="https://github.com/apple/swift-evolution/pull/346" class="">https://github.com/apple/swift-evolution/pull/346</a></div><div class=""><br class=""></div><div class="">Be aware that there's a bug that's being worked on:</div><div class=""><br class=""></div><div class=""><a href="https://bugs.swift.org/browse/SR-2773" class="">https://bugs.swift.org/browse/SR-2773</a></div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 19, 2016, at 12:40 PM, Andy Chou via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class="">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=""><br class=""></div><div class="">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=""><br class=""></div><div class="">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=""><br class="">Andy</div><div class=""><br class="">On Dec 19, 2016, at 10:43 AM, Nick Keets &lt;<a href="mailto:nick.keets@gmail.com" class="">nick.keets@gmail.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class="">

<title class=""></title>


<div name="messageBodySection" class="">You are probably asking for a generic solution, but for a specific struct you can implement it like this:
<div class=""><br class=""></div>
<div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Person</span> <span style="font-variant-ligatures: no-common-ligatures;" class="">{</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">func</span> <span style="font-variant-ligatures: no-common-ligatures" class="">with(name:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">, address:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">, phone:</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span><span style="font-variant-ligatures: no-common-ligatures" class="">? =</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -&gt;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Person</span> <span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span> <span style="font-variant-ligatures: no-common-ligatures" class="">name = name ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">name</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span> <span style="font-variant-ligatures: no-common-ligatures" class="">address = address ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">address</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">let</span> <span style="font-variant-ligatures: no-common-ligatures" class="">phone = phone ??</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">phone</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures: no-common-ligatures; color: #ba2da2" class="">return</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">Person</span><span style="font-variant-ligatures: no-common-ligatures" class="">(name: name, address: address, phone: phone)</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div>
</div>
<div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div>
</div>
<div name="messageReplySection" class=""><br class="">
On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;, wrote:<br class="">
<blockquote type="cite" style="margin: 5px 5px; padding-left: 10px; border-left: thin solid #1abc9c;" class="">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="">
<br class="">
What's I'm looking for is something like this (not necessarily with this syntax):<br class="">
<br class="">
struct Person {<br class="">
let name: String<br class="">
let address: String<br class="">
let phone: String<br class="">
}<br class="">
<br class="">
func f() {<br class="">
let andy = Person(name: "Andy", address: "1 Battery St., San Francisco, CA", phone: "1234567")<br class="">
let chris = andy.with(name: "Chris")<br class="">
let dave = andy.with(address: "50 Townsend St., San Francisco, CA")<br class="">
}<br class="">
<br class="">
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="">
<br class="">
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="">
<br class="">
Anyone taken a look at this before? Any suggestions?<br class="">
<br class="">
Andy<br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote>
</div>


</div></blockquote></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></div></div></body></html>