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

Tyler Fleming Cloutier cloutiertyler at aol.com
Mon May 16 01:17:10 CDT 2016

> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> on Mon May 09 2016, Matthew Johnson <matthew-AT-anandabits.com <http://matthew-at-anandabits.com/>> wrote:
>>> On May 8, 2016, at 1:51 AM, Dave Abrahams <dabrahams at apple.com> wrote:
>>> on Sat May 07 2016, Andrew Trick <atrick-AT-apple.com> wrote:
>>>>   On May 7, 2016, at 2:04 PM, Dave Abrahams <dabrahams at apple.com> wrote:
>>>>       2. Value types are not "pure" values if any part of the aggregate
>>>>       contains a
>>>>       reference whose type does not have value semantics. 
>>>>   Then Array<Int> is not a “pure” value (the buffer contained in an
>>>>   Array<Int> is a mutable reference type that on its own, definitely does
>>>>   *not* have value semantics). I don't think this is what you intend, and
>>>>   it indicates that you need to keep working on your definition.
>>>> It sounds like you’re changing the definition of value semantics to make it
>>>> impossible to define PureValue. 
>>> Not on purpose.
>>>> Does Array<T> have value semantics then only if T also has value
>>>> semantics?
>>> This is a great question; I had to rewrite my response four times.
>>> In my world, an Array<T> always has value semantics if you respect the
>>> boundaries of element values as defined by ==.  That means that if T is
>>> a mutable reference type, you're not looking through references, because
>>> == is equivalent to ===.
>>> Therefore, for almost any interesting SomeConstraint that doesn't refine
>>> ValueSemantics, then
>>> Array<T: SomeConstraint>
>>> only has value semantics if T has value semantics, since SomeConstraint
>>> presumably uses aspects of T other than reference identity.  
>>>> The claim has been made that Array always has value semantics,
>>>> implying that the array value’s boundary ends at the boundary of it’s
>>>> element values.
>>> Yes, an array value ends at the boundary of its elements' values.
>>>> That fact is what allows the compiler to ignore mutation of the
>>>> buffer.
>>> I don't know what you mean here.
>>>> It's perfectly clear that Array<T> is a PureValue iff T is a PureValue.
>>>> PureValue is nothing more than transitive value semantics.
>>> You're almost there.  “Transitive” implies that you are going to look at
>>> the parts of a type to see if they are also PureValue's.  So which parts
>>> of the Array struct does one look at, and why?  Just tell me the
>>> procedure for determining whether a type is a PureValue.
>> We look at the observable parts.  
> That begs the question.  The “parts” of an Array are the observable
> features that are considered by equality.
>> We do not look at unobservable parts because we want flexibility to
>> use things like CoW, shared immutable references, etc in our
>> implementation.
> IMO the important thing when it comes to functional purity is not what
> you *can* observe, but what you *do* observe.
>> Can you share your definition of value semantics?  
> Explaining it well and in sufficient detail for this discussion takes
> some doing, but I think John Lakos and I share an understanding of value
> semantics and he has a really detailed explanation in
> https://www.youtube.com/watch?v=W3xI1HJUy7Q <https://www.youtube.com/watch?v=W3xI1HJUy7Q> and
> https://www.youtube.com/watch?v=0EvSxHxFknM <https://www.youtube.com/watch?v=0EvSxHxFknM>.  He uses C++ in places,
> but it's not particularly advanced, and the fundamental ideas apply just
> as well to Swift.

Super interesting talk! 

But consider: isn't a single value type able to represent *multiple* ethereal types?

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*

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.

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. It’s not always the case that you have access to either the documentation or the implementation.

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. 

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.

I really apologize if this seems like rambling again, but I am very interested in this problem.


>> It may be helpful
>> if we start there and refine your definition to exclude impure value
>> types like Array<UIView>.
>> In the meantime I’ll take another shot:
>> 1. Scalars are pure values.
>> 2. Any aggregate type with value semantics is a pure value iff all
>>   observable parts of the aggregate are pure values.
> -- 
> -Dave
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160515/fcde4f86/attachment.html>

More information about the swift-evolution mailing list