[swift-evolution] Proposal: Intermediate mutation qualifier for protocol functions on reference-types

Josh Avant mailinglists at iamjo.sh
Fri Dec 11 16:14:33 CST 2015


It seems it would be difficult to write fully generic code with a protocol
that has this behavior, because you cannot rely on value semantics at all.
To implement ‘mutating’ class methods correctly, you would in fact have to
create a new class instance and re-assign to self every time, to preserve
old references, since mutating the old value might break users of the
protocol that are written as if the witness was a value type. This seems to
defeat the whole purpose of using a reference type in fact.


Agreed. That description even seems to sound like a rehashing of the same
problem, but from a more strictly value-centric approach.

The 'one-element struct' solution isn't what I was looking for, here. I
wasn't trying to achieve copy-on-write of a whole object structure, but
instead writing more fully generic code. Also, not having to use an awkward
workaround (i.e. the var this = self; this.mutatingMethod()).


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?


I think so. But I think part of the problem is that protocol members are
currently interpreted in terms of value semantics, but protocols are, of
course, widely used in reference semantics, too.

To me, it feels like we're lacking a degree of fidelity. That's why my
initial proposition was a `mutating`-ish operator that applies specifically
to this scenario, and provides a more nuanced bridging to reference
semantics (feels vaguely similar in nature to unowned vs. weak modifiers).

On Fri, Dec 11, 2015 at 11:44 AM, Slava Pestov <spestov at apple.com> wrote:

>
> On Dec 11, 2015, at 11:43 AM, Gwendal Roué <gwendal.roue at gmail.com> wrote:
>
>
> Le 11 déc. 2015 à 20:34, Slava Pestov via swift-evolution <
> swift-evolution at 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151211/eec05c0f/attachment.html>


More information about the swift-evolution mailing list