[swift-evolution] Should we rename "class" when referring to protocol conformance?
L. Mihalkovic
laurent.mihalkovic at gmail.com
Mon May 16 02:54:37 CDT 2016
Regards
(From mobile)
> On May 16, 2016, at 8:39 AM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>
>
>> on Sun May 15 2016, Tyler Fleming Cloutier <cloutiertyler-AT-aol.com> wrote:
>>
>> 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> 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.
>>
>> 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.
>
>>
>> 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.
>
>> 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.
>
>> 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.
AMEN....
> 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.
>
>> Tyler
>>
>> 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
>
> --
> -Dave
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list