<div dir="ltr"><div><b>Paul Cantrell:</b> </div><div><i><br></i></div><div><i>> “Ah, OK, sure … but why is this a problem? You changed the declaration! Of course it behaves differently. Changing a declaration can transparently change behavior in any number of circumstances. The following code still compiles if you change “Int” to “UInt8,” but it crashes:”</i></div><div><br></div><div>Good point, but I still think this is on a different class of problem because 1) it’s really hard to track where we were relying on value semantics before and adapt it to using classes and 2) the sort of bugs that would creep out wouldn’t probably be crashes but weird side-effects incredibly hard to track.</div><div><br></div><div><b>David Owens II:</b> </div><div><br></div><div>> <i>"<span style="line-height:1.5">Did you mean “var” there? (sidenote: var is being removed from the function call site)"</span></i></div><div><span style="line-height:1.5"><br></span></div><div>Yes I meant it, or it won’t compile. You’re right, they’re equivalent. Oh the `var` is being deprecated there? Nice to know :)</div><div><br></div><div>> <i>"<span style="line-height:1.5">I agree that this type of refactoring is inherently fragile, but I don’t see how having “immutable” structs changes this."</span></i></div><div><br></div><div>It would solve it (although quite indirectly) because we couldn’t have had code that mutated the structure before the said refactoring. In other words, since we weren’t relying on the value semantics before (because of immutability) then refactoring to classes wouldn’t be fragile. </div><div><br></div><div><b>Rudolf Adamkovič:</b> </div><div><br></div><div>> <i>"<span style="line-height:1.5">Isn’t there a better keyword (than “mutating”) that we could use here?"</span></i></div><div><i><span style="line-height:1.5"><br></span></i></div><div>I don’t understand why we need the `mutating` keyword in the first place. Is it for readability? Right now the compiler knows when a function mutates a property and forces us to write `mutating`. Couldn’t it just fail compiling when try to call a mutation function but we’re not allowed?</div><div><br></div><div><span style="font-weight:bold;white-space:nowrap">Douglas Gregor:</span><br></div><div><br></div><div><div>I realize there’s substantial personal opinion involved in this - and I’m vastly outnumbered here :) Still, I’m replying with my thoughts after watching your presentation. Maybe that clarifies some of my points and, who knows, even increases my odds to 1%?</div><div><br></div><div>-- The temperature class example <span style="line-height:1.5">--</span></div><div>You make a point of how shared references sometimes result unintended consequences. However, they’re only unintended because the fictional developer in the example is using classes and expects value semantics. Couldn’t one make the opposite argument, where the developer expected reference semantics while using structures?</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Immutability sometimes leads to awkward interfaces</div><div>This is the "awkward" version from the video:</div><div>`home.oven.temperature = Temperature(fahrenheit: temp.fahrenheit + 10.0)`</div><div><br></div><div>You could make it not awkward by implementing `+` and `-` in the global scope so it adds numbers and `Temperature` together. This would bring it back to:</div><div>`home.oven.temperature = temp + 10.0`. You already do it with strings: `let foobar = "Foo" + "Bar"`.</div><div><br></div><div>By the way, structures as value types (arguably) create some awkwardness and certainly add special cases to the language</div><div>1) `let` and `var` aren’t just about reassignment anymore. It depends on the context: for classes it’s still about reassignment; for structures it’s about reassignment and mutability (well, also depending on whether the properties of the structure are `let` or `var` themselves).</div><div>2) the `mutating` keyword on protocol extensions is only there for structures and enums - and doesn’t even enforce them to actually mutate anything.</div><div>3) the class specific protocol extensions.</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Immutability does not map efficiently to the machine model <span style="line-height:1.5">--</span></div><div>Yes, but that’s only an issue if the language is 100% immutable.</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Integers are value types<span style="line-height:1.5"> </span><span style="line-height:1.5">--</span></div><div>Aren’t they also immutable?</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Arrays are value types<span style="line-height:1.5"> </span><span style="line-height:1.5">--</span></div><div>Why? I would honestly like to know. I think all languages I’ve used in the past had arrays as reference types. Is it just because of equality? </div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>CGPoints are value types<span style="line-height:1.5"> </span><span style="line-height:1.5">--</span></div><div>Other than digging into the documentation, how can we tell it has value semantics? We can’t just skim the code and understand it anymore - we have to dig into class/structure definitions to figure out whether each thing is a value or reference. And we’ll have to do it constantly because things that work with structures would be disastrous for classes.</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Freedom from race conditions<span style="line-height:1.5"> </span><span style="line-height:1.5">--</span></div><div>Only accidental race conditions. Often memory is shared because it must be. Those are the tricky ones to solve.</div><div><br></div><div><span style="line-height:1.5">--</span><span style="line-height:1.5"> </span>Reference types as properties of structures<span style="line-height:1.5"> </span><span style="line-height:1.5">--</span></div><div>Why even allow it? Isn’t the whole point of structures to be used in small, simple cases? Allowing reference types inside opens up a can of worms with these “forReading/forWriting” methods…</div><div><br></div><div>Finally, thanks for the link to the video Douglas. I hope I didn’t sound combative. It wasn’t my intention. Sadly I wasn't converted. Perhaps next year? :)</div></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 23, 2015 at 6:13 PM Matthew Johnson <<a href="mailto:matthew@anandabits.com">matthew@anandabits.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
<br>
Sent from my iPad<br>
<br>
> On Dec 23, 2015, at 3:57 PM, Douglas Gregor via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br>
><br>
><br>
>> On Dec 23, 2015, at 7:44 AM, Lino Rosa via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br>
>><br>
>> I believe the language would be improved by making structures immutable.<br>
>><br>
>> 1) The choice between classes and structures isn’t clear right now. If structures were immutable it would be natural to use them as value objects.<br>
>><br>
>> 2) Refactoring a mutable structure into a class when it’s being passed around multiple threads removes the by-value semantics seamlessly. The resulting mutable class isn’t thread-safe.<br>
>><br>
>> 2.1) Even when passed around a single thread, the resulting class would be passed by reference, so any mutations would have unintended consequences.<br>
>><br>
>> 3) We could probably remove some syntax: `mutating` keyword and variable parameters. Also the `var` keyword before a structure could be used to denote reassignment (not mutability), just as it does with classes.<br>
>><br>
>> Of corse I might not be seeing the whole picture, so please weigh in.<br>
><br>
> Swift’s structures, enums, and standard library collections provide value semantics, which is far more useful than true immutability because it gives you immutability guaranteed when you want them (“let”) and efficient local mutation when you need it (“var”) . If you haven’t seen the “Building Better Apps with Value Types in Swift” talk from WWDC 2015, I suggest you check it out to get a sense of how value types work in Swift:<br>
><br>
> <a href="https://developer.apple.com/videos/play/wwdc2015-414/" rel="noreferrer" target="_blank">https://developer.apple.com/videos/play/wwdc2015-414/</a><br>
><br>
> We’re very happy with value semantics as a programming model, so the likelihood of moving to a model where a value of struct type is always immutable is effectively zero. My hope is that the talk above—or other resources about value semantics in Swift—will convince you as thoroughly as it convinced us ;)<br>
<br>
+1,000,000. This is one of the best aspects of Swift IMO.<br>
<br>
<br>
><br>
> - Doug<br>
><br>
><br>
> _______________________________________________<br>
> swift-evolution mailing list<br>
> <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>