> On May 16, 2016, at 1:39 AM, Dave Abrahams <dabrah...@apple.com> wrote: > > > on Sun May 15 2016, Tyler Fleming Cloutier <cloutiertyler-AT-aol.com > <http://cloutiertyler-at-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? > > “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. 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.
Looking forward to hearing your thoughts on the code I just posted. In addition to that, I think it is also important to note that contained within the notion of PureValue is thread safety. For example, in CSP PureValues would can be sent as messages on a channel. Clearly sending Array<MutableReferenceType> over a channel is something you would not do in CSP. You can also freely share a ImmutableBox<MyPureValue> and read from it in any thread you wish without any trouble. You cannot do that with ImmutableBox<Array<MutableReferenceType>>. In the latter, you cannot mutate the array, but you can still mutate the objects it contains references to. > >> 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 >> > > -- > -Dave
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution