<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 class=""><br class=""></div><div class="">Comments inline</div><div class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">A “mutating” keyword on a protocol method is only useful if
you can reason about the mutation in generic code.  

  protocol P {
    mutating func changeMe()
    func noChange() -&gt; Int
  }

In other words, given x of some type conforming to P, it should be
meaningful that this is an error:

  func f&lt;T: P&gt;(x: T) {
    immutable.changeMe() // can't mutate a "let" binding
  }
</pre></blockquote><div class=""><br class=""></div><div class="">Agreed.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">which means that you shouldn't be able to get around that meaning by
writing:

  func g&lt;T: P&gt;(x: T) {
    var mutable = x
    mutable.changeMe() // OK
  }
</pre></blockquote><div class="">Now I am confused. &nbsp;Why should this be illegal? &nbsp;Doesn’t this work with structs right now? (you are working on a mutable copy)</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">Also, you should be able to reason that both of the following print the same
thing twice, for types whose methods have no external side-effects:

  func gg&lt;T: P&gt;(x: T) {
    print(x)
    x.noChange()
    print(x)
  }

  func ggg&lt;T: P&gt;(x: T) {
    print(x)
    var y = x
    y.changeMe()
    print(x)
  }
</pre></blockquote><div class="">I see the issue here. &nbsp;Though, it seems to me it is just a more easily discoverable version of an entire class of problem with reference types in general. X could be changed on a different thread too, for example. &nbsp;or in a nested function call.</div><div class=""><br class=""></div><div class="">You would also still have the same problem with 'let y = x'.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">When T is a class type, it can easily violate *all* of these
expectations.  In other words, classes naturally bypass the mutation
model.

If we are going to maintain source stability after Swift 3, it seems
that we either need to address this now, or decide that it won't be
addressed, because of the “viral const” problem.

One idea that Jordan and I have floated is that protocols with mutating
methods should be constrained to applying to non-class types.  That
would be a step in the right direction, but, that still leaves cases
like gg able to easily violate expectations when the protocol in
question has no mutating methods.
</pre></blockquote><div class="">I really *dislike* the approach of disallowing class types for protocols with mutating methods, unless an additional reference type is added. &nbsp;I have several protocols which have conforming classes and structs and that that lets you choose reference vs value semantics.</div><div class=""><br class=""></div><div class="">I would much rather have us mark class methods as mutating when they change the class’s value, and just having the concept be separate from let/var in that case.</div><br class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">
Another possibility would be to formalize the idea of value semantics in
protocol declarations, so that non-class protocols were only allowed to
apply to values.
</pre></blockquote>I would like to have a way to require value semantics in a protocol (similar to how we can require ‘class' now). &nbsp;I still really want/need the ability to have a protocol which can be adhered to by both value and class types though...</div><div class=""><br class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">It's also possible that I've overestimated the seriousness of the issue
and we actually can afford to postpone thinking about it until after
Swift 4.

Thoughts?</pre></blockquote><div class="">I would vote to postpone to swift 4, and have it be part of a larger discussion involving the marking of side-effects and thread safe mutability.</div><div class=""><br class=""></div><div class="">If you need a stop-gap for Swift 3, I would be in favor of adding the ability to mark a particular protocol as needing to be a value type (not every protocol… just those that are marked as such). &nbsp;That should give you the guarantees you need for particular projects.</div><div class=""><br class=""></div>Thanks,</div><div class="">Jon</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><br class=""></div></div></body></html>