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

Dave Abrahams dabrahams at apple.com
Sun May 15 13:48:02 CDT 2016


on Mon May 09 2016, Matthew Johnson <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 and
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.

> 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


More information about the swift-evolution mailing list