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

Dave Abrahams dabrahams at apple.com
Mon May 16 04:16:04 CDT 2016


on Mon May 16 2016, Tyler Fleming Cloutier <cloutiertyler-AT-aol.com> wrote:

>>> Super interesting talk! 
>>> 
>>> But consider: isn't a single value type able to represent *multiple*
>>> ethereal types?
>> 
>> “ethereal?”  Does he really use that term?  I don't know what it means.
>
> He does pretty frequently. He also refers to them as Mathematical
> Types. He means the logical type that the C++ implementation is
> supposed to approximate.

OK.

> An example he gives is int and how it only approximates the logical
> Integer type, because it is represented in many ways, e.g. short, int,
> long, long long. None of them are exactly the same the logical type.

Check.

>>> std::vector is a good example. What are the salient attributes of this
>>> type? In the talk John says that
>>> 
>>> 1. the size is
>>> 2. the values in the vector are
>>> 3. the capacity, however *is not*
>> 
>> Yup, just like Array.  Thus the equality test for arrays ignores
>> capacity.
>> 
>>> in which case std::vector would be an approximation of an ethereal
>>> type which has a list of values, and the capacity is just an artifact
>>> of the approximation. But you could also imagine an ethereal type
>>> which *does* depend of the capacity of the object, and std::vector
>>> unwittingly approximates that type too! 
>>> In this case someone, unfamiliar with the implementation might use
>>> it under the assumption that capacity *is* part of the ethereal type
>>> and by extension the equality of std::vector.
>>> 
>>> John avoids the problem by saying that this must specified in the
>>> documentation.
>> 
>> Yes.
>> 
>>> I tend to see this as breaking encapsulation since you need to know
>>> the implementation of the equality operator to be able to determine if
>>> a public property, the capacity, is part of the ethereal type. 
>> 
>> No, you just need documentation.
>> 
>>> It’s not always the case that you have access to either the
>>> documentation or the implementation.
>> 
>> Without the documentation, you're lost.  We go a lot further with naming
>> conventions in Swift than typical C++ does, but even in Swift you can't
>> expect to fully understand semantics without documentation.
>
> Swift also goes a lot further with enforcing things like immutability
> by default with let, particularly for value types. I think that with
> well defined rules you can go further with what’s enforced, and remove
> the need for documentation, especially since the distinctions with
> regards to value types can be subtle.

Remove the need for documentation! Good luck with that, my friend.

>>> This implies, therefore, that if salient attributes *define* the
>>> immutability of the value type, then the public interface is not
>>> guaranteed to be immutable, since it is allowed to include non-salient
>>> attributes. For example, a vector’s capacity could change at any time,
>>> by virtue of it being stored via a reference.
>>> 
>>> What I am saying is that a PureValue is a value type whose public
>>> interface comprises *only* salient attributes. And I also claim that
>>> this is a useful distinction amongst value types.
>> 
>> Then Array<Int> is not a PureValue because it exposes capacity?!  That
>> sounds crazy to me, since the Array's capacity in no sense has reference
>> semantics.
>
> I would argue, rather, that capacity for Array<Int> *is* a salient
> attribute, by virtue being public 

Then you're missing the point.  There would be no point in making the
distinction “salient” if all public API were salient.  Lakos only
considers public API.

> and that Array<Int> is a PureValue by virtue of it not having
> reference semantics. This I propose is valid, because even though it’s
> not the most intuitive in this case, it is possible that some
> algorithm interprets capacity to be salient and relies on two arrays
> with different capacities being not equal.
>
> I can certainly understand the opposing argument here, but at least
> this way it is unambiguous.

Capacity, in Lakos' terms, is non-salient, and that's unambiguous.

>>> John also says that a salient attribute must derive *only* from the
>>> state of a particular instance of a type. This by extension implies
>>> that a salient attribute must derive exclusively from pure
>>> values. However, this also means that without some “indirect” keyword,
>>> PureValues are restricted to acyclic and non-recursive structures.
>>> 
>>> I also claim that equality can be automatically generated for
>>> PureValues by equating each of there salient attributes.
>> 
>> That's true for almost any value, provided we define equality for
>> reference types properly.
>> 
>>> I really apologize if this seems like rambling again, but I am very
>>> interested in this problem.
>> 
>> I'm glad you are! Few programmers dig far enough to understand value
>> semantics at a deep level.
>> 
>> All that said, I still think PureValue is a red herring.  Unless I'm
>> forgetting something that happened in the thread two weeks ago, nobody
>> has shown me code that relies on PureValue but could not equally well be
>> written by using a Value constraint.
>
> Let me get back to you here. I need to do more investigation!
>
> Gotta watch that second video.

Enjoy!

-- 
-Dave


More information about the swift-evolution mailing list