[swift-evolution] Should we rename "class" when referring to protocol conformance?

Dave Abrahams dabrahams at apple.com
Sat May 7 15:03:38 CDT 2016

on Sat May 07 2016, Matthew Johnson <matthew-AT-anandabits.com> wrote:

> This depends on the type. For types representing resources, etc it works just
> fine. But for models it does not work unless the model subgraph is entirely
> immutable and instances are unique. 
> I agree that it isn't a good idea to provide a default that will
> certainly be wrong in many cases.

Please show an example of a mutable model where such an equality would
be wrong.  

>     I assume what is meant by "PureValue", is any object A, whose own references
>     form a subgraph, within which a change to any of the values would constitute
>     a change in the value of A (thus impermissible if A is immutable). Thus
>     structs would quality as “PureValues”.
> As you noted in a followup, not all structs qualify. Structs that whose members
> all qualify will qualify. References to a subgraph that doesn't allow for any
> observable mutation (i.e. deeply immutable reference types) also qualify.
> This means the following qualify:
> * primitive structs and enums
> * observable immutable object subgraphs
> * any type composed from the previous
> It follows that generic types often conditionally qualify depending on their
> type arguments.
>     I also assume that enforcing immutability on an object graph, via CoW or
>     otherwise, would be unfeasible. You could enforce it on all values
>     accessible by traversing a single reference for reference types, however.
>     This is why I don’t really buy the argument that there is no such this as
>     deep vs shallow copy. Deep copy means copying the whole “PureValue” or
>     subgraph, shallow copy means traversing a single reference and copying all
>     accessible values.
>                 I don’t mean to imply that it is the *only* valuable
>             property. However, it I (and many others) do believe it is an
>             extremely
>             valuable
>             property in many cases. Do you disagree?
>             I think I do. What is valuable about such a protocol? What generic
>             algorithms could you write that work on models of PureValue but
>             don't
>             work just as well on Array<Int>?
>             Array<Int> provides the semantics I have in mind just fine so there
>             wouldn’t be
>             any. Array<AnyObject> is a completely different story. With
>             Array<AnyObject> you cannot rely on a guarantee the objects
>             contained
>             in the array will not be mutated by code elsewhere that also happens
>             to have a reference to the same objects.
>         Okay then, what algorithms can you write that operate on PureValue that
>         don't work equally well on Array<AnyObject>?

You haven't answered this question.  How would you use this protocol?

>             let t = MyClass()
>             foo.acceptWrapped(Wrap(t))
>             t.mutate()
>             In this example, foo had better not depend on the wrapped instance
>             not
>             getting
>             mutated.
>             foo has no way to get at the wrapped instance, so it can't depend on
>             anything about it.
>             Ok, but this is a toy example. What is the purpose of Wrap? Maybe
>             foo
>             passes the
>             wrapped instance back to code that *does* have visibility to the
>             instance. My
>             point was that shared mutable state is still possible here. 
>             And my point is that Wrap<T> encapsulates a T (almost—I should have
>             let
>             it construct the T in its init rather than accepting a T parameter)
>             and
>             the fact that it's *possible* to code something with the structure
>             of
>             Wrap so that it has shared mutable state is irrelevant.
>             The point I am trying to make is that the semantic properties of
>             Wrap<T> depend
>             on the semantic properties of T (whether or not non-local mutation
>             may be
>             observed in this case). 
>         No they do not; Wrap<T> was specifically designed *not* to depend on the
>         semantic properties of T. This was in answer to what you said:
>                 A struct wrapping a mutable reference type certainly doesn’t
>             “feel” value semantic to me and certainly doesn’t have the
>             guarantees usually associated with value semantics (won’t
>             mutate behind your back, thread safe, etc).
>         I have been trying to get you to nail down what you mean by PureValue,
>         and I was trying to illustrate that merely being “a struct wrapping a
>         mutable reference type” is not enough to disqualify anything from being
>         in the category you're trying to describe. What are the properties of
>         types in that category, and what generic code would depend on those
>         properties?

Again, the key questions are above, asked a different way.


More information about the swift-evolution mailing list