> On May 16, 2016, at 9:21 AM, Matthew Johnson <matt...@anandabits.com> wrote: > > >>> On May 16, 2016, at 1:17 AM, Tyler Fleming Cloutier <cloutierty...@aol.com> >>> wrote: >>> >>> >>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution >>> <swift-evolution@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 <dabrah...@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 <dabrah...@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? >> >> 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. > > I don't agree with this. I consider Array<Int> to be a pure value. If it > exposes a capacity property that fact is incidental to its value. I agree > with John here.
Yes, I revised my statement in a later email. I agree with you here. > >> >> 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. >> >> 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@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution