<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On Aug 19, 2017, at 9:33 PM, Brent Royal-Gordon &lt;<a href="mailto:brent@architechies.com">brent@architechies.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><div><blockquote type="cite" class=""><div class="">On Aug 19, 2017, at 7:41 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Regardless of which approach we take, it feels like something that needs to be implicit for structs and enums where value semantics is trivially provable by way of transitivity.&nbsp;</span>When that is not the case we could require an explicit `value` or `nonvalue` annotation (specific keywords subject to bikeshedding of course).</div></blockquote><div><br class=""></div><div>There is no such thing as "trivially provable by way of transitivity". This type is comprised of only value types, and yet it has reference semantics:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>struct EntryRef {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>private var index: Int</div><div><span class="Apple-tab-span" style="white-space:pre">                </span></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>var entry: Entry {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>get { return entries[index] }</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>set { entries[index] = newValue }</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div></div></div></blockquote><div><br></div><div>This type uses global mutable state in its implementation. &nbsp;This is not hard for the compiler to detect and is pretty rare in most code.</div><br><blockquote type="cite"><div><div><div><br class=""></div><div>This type is comprised of only reference types, and yet it has value semantics:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>struct OpaqueToken: Equatable {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>class Token {}</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>private let token: Token</div><div><span class="Apple-tab-span" style="white-space:pre">                </span></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>static func == (lhs: OpaqueToken, rhs: OpaqueToken) -&gt; Bool {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>return lhs.token === rhs.token</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div></div></div></blockquote><div><br></div><div>Yes, of course this is possible. &nbsp;I believe this type should have to include an annotation declaring value semantics and should also need to annotate the `token` property with an acknowledgement that value semantics is being preserved by the implementation of the type despite this member not having value semantics. &nbsp;The annotation on the property is to prevent bugs that might occur because the programmer didn't realize this type does not have value semantics.</div><br><blockquote type="cite"><div><div><div><br class=""></div><div>I think it's better to have types explicitly declare that they have value semantics if they want to make that promise, and otherwise not have the compiler make any assumptions either way. Safety features should not be *guessing* that your code is safe. If you can somehow *prove* it safe, go ahead—but I don't see how that can work without a lot of manual annotations on bridged code.</div></div></div></blockquote><div><br></div><div>I agree with you that *public* types should have to declare that they have value semantics. &nbsp;And I'm not suggesting we attempt to *prove* value semantics everywhere. &nbsp;</div><div><br></div><div>I'm suggesting that the proportion of value types in most applications for which we can reasonably infer value semantics is pretty large. &nbsp;If the stored properties of a value type all have value semantics and the implementation of the type does not use global mutable state it has value semantics. &nbsp;</div><div><br></div><div>Whether we require annotation or not, value semantics will be decided by the declaring module. &nbsp;If we don't infer it we'll end up having to write `value struct` and `value enum` a lot. &nbsp;The design of Swift has been vigorous in avoiding keyword soup and I really believe that rule applies here. &nbsp;The primary argument I can think of against inferring value semantics for non-public value types in these cases is if proving a type does not use global mutable state in its implementation would have too large an impact on build times.</div><br><blockquote type="cite"><div><br class=""><div class="">
<span class="Apple-style-span" style="border-collapse: separate; font-variant-ligatures: normal; font-variant-east-asian: normal; font-variant-position: normal; line-height: normal; border-spacing: 0px;"><div class=""><div style="font-size: 12px; " class="">--&nbsp;</div><div style="font-size: 12px; " class="">Brent Royal-Gordon</div><div style="font-size: 12px; " class="">Architechies</div></div></span>

</div>
<br class=""></div></blockquote></body></html>