Proposal: Intermediate mutation qualifier for protocol functions on reference-types

BTW, we have three workarounds to the initial problem so far, using the current state of Swift:

1. the one by Kevin Ballard below in the thread (the best one)
2. my first work around at [SR-142] mutating function in protocol extension erroneously requires `var` declaration of class variables · Issue #42764 · apple/swift · GitHub
3. declare a non-mutating protocol that inherits from the mutating one, and let classes adopt the non-mutating one, as in:

  protocol MutableP {
    mutating func f()
  }
  protocol P : MutableP {
    func f()
  }

The last workaround is a different in that it leaves room for structs that decide not to mutate in their implementation of the protocol.

You have an example of this approach at GitHub - groue/GRDB.swift: A toolkit for SQLite databases, with a focus on application development

Gwendal Roué

···

Le 11 déc. 2015 à 20:44, Slava Pestov <spestov@apple.com> a écrit :

On Dec 11, 2015, at 11:43 AM, Gwendal Roué <gwendal.roue@gmail.com <mailto:gwendal.roue@gmail.com>> wrote:

Le 11 déc. 2015 à 20:34, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

For this reason I’m in favor of going in the opposite direction, and prohibiting classes from conforming to protocols with mutating requirements.

This would go too far.

It’s common to write a protocol with mutating methods just because the protocol designer expects that some adopting structs may want to mutate in their implementation. And in this case the goal of the protocol designer is certainly not to limit the protocol adoption to structs.

Here is an example:

  protocol DatabaseFetchable {
    mutating func awakeFromFetch()
  }
  extension DatabaseFetchable {
    func fetch() -> Self {
      var value = /* details omitted */
      value.awakeFromFetch()
      return value
    }
  }

The protocol does not care at all if awakeFromFetch mutates or not. But the protocol designer does: if the awakeFromFetch method were not declared mutating, many structs could simply not adopt it.

Gwendal Roué

I guess the question is, does it even make sense to write a protocol that can be adopted by both a struct and a class, if the protocol has mutating members?

Slava