<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">For instance, has Array<UIView> value semantics? </div></div></div></blockquote><div class=""><br class=""></div><div class="">By the commonly accepted definition, Array<UIView> does not provide value semantics.</div></div></div></div></blockquote><div><blockquote type="cite" class=""><br class=""></blockquote></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">You might be tempted to say that it does not because it contains class references, but in reality that depends on what you do with those UIViews.</div></div></div></blockquote><div class=""><br class=""></div><div class="">An aspect of the type (“does it have value semantics or not”) should not depend on the clients. By your definition, every type has value semantics if none of the mutating operations are called :-)</div></div></div></div></blockquote><br class=""><div>No, not mutating operations. Access to mutable memory shared by multiple "values" is what breaks value semantics. You can get into this situation using pointers, object references, or global variables. It's all the same thing in the end: shared memory that can mutate.</div><div><br class=""></div><div>For demonstration's sake, here's a silly example of how you can give Array<Int> literally the same semantics as Array<UIView>:</div><div><br class=""></div><div><div><span class="Apple-tab-span" style="white-space: pre;">        </span>// shared UIView instances in global memory</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>var instances: [UIView] = []</div><div><br class=""></div></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>extension Array where Element == Int {</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// append a new integer to the array pointing to our UIView instance</div><div><div><span class="Apple-tab-span" style="white-space: pre;">                </span>func append(view: UIView) {</div><span class="Apple-tab-span" style="white-space: pre;">                        </span>self.append(instances.count)</div><div><span class="Apple-tab-span" style="white-space: pre;">                        </span>instances.append(newValue)<div><span class="Apple-tab-span" style="white-space: pre;">                </span>}</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// access views pointed to by the integers in the array</div></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>subscript(viewAt index: Int) -> UIView {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>get {</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>return instances[self[index]]</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>set {</div><span class="Apple-tab-span" style="white-space: pre;">                                </span>self[index] = instances.count<div><span class="Apple-tab-span" style="white-space:pre">                                </span>instances.append(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><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div>And now you need to worry about passing Array<Int> to other thread. ;-)</div><div><br class=""></div><div>It does not really matter whether the array contains pointers or wether it contains indices into a global table: in both cases access to the same mutable memory is accessible through multiple copies of an array, and this is what breaks value semantics.</div><div><br class=""></div><div>Types cannot enforce value semantics. Its the functions you choose to call that matters. This is especially important to realize in a language with extensions where you can't restrict what functions gets attached to a type.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""> If you treat the class references as opaque pointers (never dereferencing them), you preserve value semantics. You can count the elements, shuffle them, all without dereferencing the UIViews it contains. Value semantics only end when you dereference the class references. And even then, there are some exceptions.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I agree with you that the model could permit all values to be sent in actor messages, but doing so would give up the principle advantages of mutable state separation. You’d have to do synchronization, you’d have the same bugs that have always existed, etc.</div></div></div></div></blockquote><br class=""></div><div>What the compiler should aim at is enforcing useful rules when it comes to accessing shared mutable state.</div><div><div class=""><br class=""></div></div><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" 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 style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">-- <br class="">Michel Fortin</div><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span style="text-align: -webkit-auto;" class=""><a href="https://michelf.ca" class="">https://michelf.ca</a></span></div></span></div></span></div></span></div></div></div></div>
</div>
<br class=""></body></html>