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

2016-05-23 Thread Dave Abrahams via swift-evolution

on Sun May 22 2016, Matthew Johnson  wrote:

> Are you sure that is Sean’s entire point? I take more away from it than that.
> Look at slide 13 here:
> https://github.com/boostcon/cppnow_presentations_2012/blob/master/fri/value_semantics/value_semantics.pdf
>
> “The shared structure also breaks our ability to reason locally about code”. 
>
> But I know you agree with that as well as you indicated just up thread. 
>
> It sounds like the only remaining point of possible disagreement is whether
> “can’t reach shared mutable state” is a reasonable constraint to place on 
> types
> in generic code.

Here's what Sean sent me this morning:

> Hi Dave,
> 
> I've now had several people send me this transcript. I'm not seeing
> 
> Although I'm sure you know this - the short definition of regular is:
> 
>   copies are equal and logically disjoint.
> 
> Logically disjoint means that modifications to one copy do not modify
> other copies. It does not mean "no sharing" - sharing of an immutable
> part, a copy-on-write part (immutable when shared) or a part which is
> outside the definition of equality (such as a cache) are all
> allowed. We can write out all the axioms for a regular type if that
> would help. I do not know what the axioms of a "pure value" are, or
> how they would differ from this definition. Typically in functional
> programming (where "pure" is used to refer to functions that have no
> side effects) a value is not mutable and so the notion of disjoint
> does not come into question and there is typically significant
> sharing.
> 
> For "pure value" to be a useful concept we need an instance of a
> model, an algorithm that relies on the additional requirements, and
> the axioms that define it. From the thread it seems as if the
> definition is something like "copies are equal and physically
> disjoint." I'm not sure if there is something else people are trying
> to say along the lines that all parts are included in equality. I do
> not see any compelling evidence in the description that there are
> useful algorithms that rely on such attributes. Note that concepts are
> about enabling additional algorithms, including for efficiency.
> 
> [ Feel free to quote this back to the list - I can be easily reached
> at spar...@adobe.com if people have questions instead of speculating
> about what I did, or did not, mean in my talks. ]
> 
> Sean

...and now, I really need to get back to work on *my* talk for WWDC.

Cheers,

-- 
Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-23 Thread Matthew Johnson via swift-evolution

> On May 23, 2016, at 11:19 AM, Patrick Smith  wrote:
> 
> I just want to highlight the Photoshop history example. I agree you’d want as 
> much state and memory shared between steps in the history.
> 
> However, I see nothing wrong with having pointers to pixel buffer, and that 
> affecting the ‘purity’ of the state.

I don’t have a problem with pointers to pixel buffers.  What I have a problem 
with is pointers to shared mutable state.  All you need to do is implement a 
value type that wraps the pointer and performs CoW before updating.  Now you 
have an efficient pixel buffer that is a pure value type.

> The way Photoshop’s history is implemented, is every image is broken up into 
> tiles. Changes are recorded only within touched tiles. 
> (http://www.photoshopforphotographers.com/CC_2013/Help_guide/tp/History_palette.html
>  
> )
>  This improves memory usage compared to a single pixel buffer.

Yep, I know how it is implemented and believe I described this upthread.  

> With a graphics programming workflow, say where a background thread or the 
> GPU is involved, the contents of those pixel buffers are going to change 
> independently to the history stack. I think there would no problem for the 
> history steps to have pointers to their mutable pixel buffers. Once the 
> thread/GPU has finished processing changes within a step’s pixel buffer, it 
> is ‘sealed’ say with a flag, and can’t be mutated later.

If you don’t know what the new value is synchronously then it certainly isn’t 
quite as simple.  But you can still encapsulate this in a type that holds the 
pointer, performs CoW when necessary, and ensures that the pixel buffer isn’t 
written to other than by the job that is processing the pixels for this step.  
The physical pixels are mutated, but the “logical value” isn’t.  The logical 
value is the result of a pure function “applyEditToPixels(oldPixels)” which is 
captured by the new step in the history.  The mutation is tightly encapsulated 
as an implementation detail.  

I agree that we need to allow for implementation details like this.  But we 
should find other ways when possible.  And we should probably have to be 
explicitly clear about our intent if we want to implement a pure value which is 
hiding an implementation like this.

> 
> The only other way I could think of is for each history step to use UUIDs to 
> reference tile pixel buffers, and manage a separate map of [UUID: 
> PixelBuffer]. Possibly this approach might have other benefits, but I think 
> it doesn’t differ practically in ‘purity’ of state vs one state tree 
> involving pointers. The purity is from the point of view of the programmer, 
> where they know their system is purely additive.
> 
> The guarantee is in the system the programmer has created. Not allowing 
> pointers to carefully managed mutable state is too rigid.

I am not suggesting they shouldn’t be allowed.  I absolutely agree that they 
*should* be allowed!  This is one reason why I love Swift!  It blends 
functional and imperative in a very nice way.

It seems likely that we will eventually have ownership semantics of some kind 
in Swift.  When we have that we will have the ability to have unique references 
to mutable state.  I have no problem viewing that as a pure value, because the 
mutation is local.  It is really no different than a `var Int`, it is just 
indirect.

However, if we share references to the mutable state then we are introducing 
potential for non-local mutation.  I believe it is extremely useful to have 
*parts* of our program that don’t allow for this, and ideally get the compilers 
help with ensuring this.

I hope that doesn’t seem like to rigid a request!  I want *choice* not rigidity!

> 
> 
>> On 23 May 2016, at 5:12 AM, Matthew Johnson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On May 22, 2016, at 12:04 PM, Dave Abrahams via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> on Mon May 16 2016, Matthew Johnson >> > wrote:
>>> 
> On May 15, 2016, at 2:01 PM, Dave Abrahams
> mailto:dabrah...@apple.com>> wrote:
> 
> 
> on Fri May 13 2016, Matthew Johnson  
> >> 
> wrote:
> 
 
>> Sent from my iPad
>> 
>>> On May 13, 2016, at 9:12 AM, Dave Abrahams >> > wrote:
>>> 
>>> 
 on Mon May 09 2016, Matthew Johnson >>> > wrote:
 
 My claim is that substituting the constraint of “it has value
 semantics,” while presumably looser than the PureValue constraint, 
 would
 not compromise the correctness of your view controller, so not only is
 the meaning of PureValue hard to define

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

2016-05-23 Thread Matthew Johnson via swift-evolution

> On May 23, 2016, at 9:22 AM, Dave Abrahams  wrote:
> 
> 
> on Sun May 22 2016, Matthew Johnson  > wrote:
> 
>>> On May 22, 2016, at 3:42 PM, Dave Abrahams via swift-evolution
>>>  wrote:
>>> 
>>> 
>>> on Sun May 22 2016, Matthew Johnson  wrote:
>>> 
 What I am arguing for is the ability to distinguish aggregates which
 are logically isolated from aggregates which contain salient
 references to shared mutable state. 
>>> 
>>> Everything with value semantics is logically isolated in that way.
>> 
>> Array has salient references whose referent is shared mutable
>> state.  The references are salient attributes. You’re saying the
>> referent doesn’t matter because the boundary of the value stops at the
>> reference.  
> 
> I'm saying you can define things that way, and it helps to make the
> model for generic programming coherent.  Without something like this, it
> becomes almost impossible to specify the behavior of generic components
> in an understandable way without simultaneously preventing the use of
> reference values as simple object identities, which *are* values.  As I
> mentioned elsewhere, we could force users to wrap these reference values
> to produce something that doesn't have easily identifiable reference
> semantics, but the requirement of your `PureValue` that there should be
> *no way* to derive access to the referenced instance from the wrapped
> reference is too limiting.
> 
>> I’m saying it does matter in that it means the aggregate is no longer
>> logically isolated because shared mutable state is reachable through
>> the aggregate.  Therefore it is not isolated in that way that I was
>> intending to describe.
> 
> This, again, is a matter of your mental model.  I do think it's
> reasonable to say that—especially in Swift where reference-ness is often
> syntactically invisible—asking people to adopt a mental model that
> *directly* treats references as values is simply unrealistic.  In that
> case, using some kind of wrapper to represent object identity might be
> the only practical way to do this.

I think the lack of syntax is a good point.  I have wondered how this would 
play out in Swift.

However, I think it goes deeper than just being syntactically invisible.  If 
Swift used C-like pointer syntax that would give us a syntactic distinction but 
not a semantic one.

Consider your `Set` example.  In this case, maybe you really do 
just care about object identity so you can test set membership.  In this case 
you really are just viewing the references as values.  In this case you really 
do view `Set` as a pure value.

Consider another example - an `Order` with an `Array`.  In this case, 
you are looking at the array as a part of an aggregate.  You don’t care about 
the values of the references at all, except as a means to get you the object.  
In this case `Array` isn’t a pure value (if `LineItem` is a type with 
reference semantics).

If we simply referred to all reference types with `*DrawableObject` syntax we 
would have to do that in both `Set<*DrawableObject>` and `Array<*LineItem>`.  
The semantic distinction isn’t captured.

However, if we use an opaque wrapper type like you suggest we actually *can* 
capture the distinction.  We can say `Set>`.  It would 
be perfectly acceptable to me to view this as a pure value because it is clear 
that you are only looking at the value of the reference, not actually following 
the reference.  And if we really needed to include “unsafeDereference” or 
something like that for performance reasons I could probably live with that.  
At least your intention is explicit.  If desired we could even introduce 
syntactic sugar for this wrapper like we have for `Optional`, `Array`, and 
`Dictionary` so you can talk about it more concisely.


> 
 To be honest, I am really struggling to understand why this
 distinction seems unimportant to you.
>>> 
>>> The non-exposure of shared mutable state is a hugely important
>>> property of well-encapsulated design.  However, I don't believe it's
>>> appropriate to represent that with a protocol, because I don't
>>> believe there exist any generic components whose correctness depends
>>> on it.
>> 
>> Do you believe it is appropriate to represent this in some other way
>> that allows us to state architectural intent and introduce constraints
>> for the purpose of structuring a large code base?
> 
> Sure, if it makes your life better, you should define it; I just don't
> see yet that it has any place in the standard library.  It is a
> principle of generic programming that protocols (concepts) are
> *discovered* through a specific process.  In the standard library, we
> don't define a new protocol until we have identified a family of
> concrete components that can be generalized based that protocol and
> whose correctness depends on the protocol's constraints.

I hope I am not coming across like I believe we should introduce this right 
now, or like I am at

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

2016-05-23 Thread Patrick Smith via swift-evolution
I just want to highlight the Photoshop history example. I agree you’d want as 
much state and memory shared between steps in the history.

However, I see nothing wrong with having pointers to pixel buffer, and that 
affecting the ‘purity’ of the state. The way Photoshop’s history is 
implemented, is every image is broken up into tiles. Changes are recorded only 
within touched tiles. 
(http://www.photoshopforphotographers.com/CC_2013/Help_guide/tp/History_palette.html
 
)
 This improves memory usage compared to a single pixel buffer. With a graphics 
programming workflow, say where a background thread or the GPU is involved, the 
contents of those pixel buffers are going to change independently to the 
history stack. I think there would no problem for the history steps to have 
pointers to their mutable pixel buffers. Once the thread/GPU has finished 
processing changes within a step’s pixel buffer, it is ‘sealed’ say with a 
flag, and can’t be mutated later.

The only other way I could think of is for each history step to use UUIDs to 
reference tile pixel buffers, and manage a separate map of [UUID: PixelBuffer]. 
Possibly this approach might have other benefits, but I think it doesn’t differ 
practically in ‘purity’ of state vs one state tree involving pointers. The 
purity is from the point of view of the programmer, where they know their 
system is purely additive.

The guarantee is in the system the programmer has created. Not allowing 
pointers to carefully managed mutable state is too rigid.


> On 23 May 2016, at 5:12 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On May 22, 2016, at 12:04 PM, Dave Abrahams via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> on Mon May 16 2016, Matthew Johnson > > wrote:
>> 
 On May 15, 2016, at 2:01 PM, Dave Abrahams
 mailto:dabrah...@apple.com>> wrote:
 
 
 on Fri May 13 2016, Matthew Johnson >>> 
 >> 
 wrote:
 
>>> 
> Sent from my iPad
> 
>> On May 13, 2016, at 9:12 AM, Dave Abrahams > > wrote:
>> 
>> 
>>> on Mon May 09 2016, Matthew Johnson >> > wrote:
>>> 
>>> My claim is that substituting the constraint of “it has value
>>> semantics,” while presumably looser than the PureValue constraint, would
>>> not compromise the correctness of your view controller, so not only is
>>> the meaning of PureValue hard to define, but it doesn't buy you
>>> anything.  If you want to refute that, just show me the code.
>>> 
>>> This is not an algorithmic use but is still perfectly valid IMO.
>>> 
>>> If the properties of PureValue matter to your view controller, there's
>>> an algorithm somewhere that depends on those properties for its
>>> correctness.
>>> 
>>> In many cases it may just be view configuration that depends on those
>>> properties.  I suppose you can call view configuration code an
>>> algorithm but I think that would fall outside of common usage.
>> It's an algorithm, or if the configuration is declarative, there's
>> an algorithm that manipulates it.  That said, I still don't have a
>> concrete example of how view configuration can depend on these
>> properties.
> The algorithm might just be "copy x bit of data to y view
> property, etc".  That is so trivial that it feels like a stretch to
> call it an algorithm.
 
 Algorithms can be trivial.
>>> 
>>> Fair enough.  Although in most contexts people don’t use the word when
>>> discussing the trivial.
>> 
>> Yes, quite a shame, that.
>> 
> That "algorithm" doesn't depend on this property because it
> executes at a single point in time.  However, a view controller
> might depend on that property in order to render properly across
> time (for example, configuring cells as they scroll on and off
> screen).
 The example is too abstract for me to understand.
 
 Let me put this differently: I recognize that your concept of
 “PureValue” may be a *sufficient* condition for some generic
 algorithm/component to work, but it is never a *necessary*
 condition, because genericity (or use of a superclass or protocol
 type) erases details of the actual types involved from the point of
 view of the algorithm/component.  It doesn't matter if your type
 contains a class reference if it has value semantic properties.  My
 claim is that PureValue is an overly-restrictive constraint that
 makes many things less useful than they should be.
>>> 
>>> In many cases this is true - you don’t need more than value semantics
>>> as you define it.  However it is not at all true that PureValue is
>>> 

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

2016-05-23 Thread Dave Abrahams via swift-evolution

on Sun May 22 2016, Matthew Johnson  wrote:

>> On May 22, 2016, at 3:42 PM, Dave Abrahams via swift-evolution
>>  wrote:
>> 
>> 
>> on Sun May 22 2016, Matthew Johnson  wrote:
>> 
>>> What I am arguing for is the ability to distinguish aggregates which
>>> are logically isolated from aggregates which contain salient
>>> references to shared mutable state. 
>> 
>> Everything with value semantics is logically isolated in that way.
>
> Array has salient references whose referent is shared mutable
> state.  The references are salient attributes. You’re saying the
> referent doesn’t matter because the boundary of the value stops at the
> reference.  

I'm saying you can define things that way, and it helps to make the
model for generic programming coherent.  Without something like this, it
becomes almost impossible to specify the behavior of generic components
in an understandable way without simultaneously preventing the use of
reference values as simple object identities, which *are* values.  As I
mentioned elsewhere, we could force users to wrap these reference values
to produce something that doesn't have easily identifiable reference
semantics, but the requirement of your `PureValue` that there should be
*no way* to derive access to the referenced instance from the wrapped
reference is too limiting.

> I’m saying it does matter in that it means the aggregate is no longer
> logically isolated because shared mutable state is reachable through
> the aggregate.  Therefore it is not isolated in that way that I was
> intending to describe.

This, again, is a matter of your mental model.  I do think it's
reasonable to say that—especially in Swift where reference-ness is often
syntactically invisible—asking people to adopt a mental model that
*directly* treats references as values is simply unrealistic.  In that
case, using some kind of wrapper to represent object identity might be
the only practical way to do this.

>>> To be honest, I am really struggling to understand why this
>>> distinction seems unimportant to you.
>> 
>> The non-exposure of shared mutable state is a hugely important
>> property of well-encapsulated design.  However, I don't believe it's
>> appropriate to represent that with a protocol, because I don't
>> believe there exist any generic components whose correctness depends
>> on it.
>
> Do you believe it is appropriate to represent this in some other way
> that allows us to state architectural intent and introduce constraints
> for the purpose of structuring a large code base?

Sure, if it makes your life better, you should define it; I just don't
see yet that it has any place in the standard library.  It is a
principle of generic programming that protocols (concepts) are
*discovered* through a specific process.  In the standard library, we
don't define a new protocol until we have identified a family of
concrete components that can be generalized based that protocol and
whose correctness depends on the protocol's constraints.

HTH,

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-22 Thread Matthew Johnson via swift-evolution

> On May 22, 2016, at 3:42 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Sun May 22 2016, Matthew Johnson  wrote:
> 
>> What I am arguing for is the ability to distinguish aggregates which
>> are logically isolated from aggregates which contain salient
>> references to shared mutable state. 
> 
> Everything with value semantics is logically isolated in that way.

Array has salient references whose referent is shared mutable state.  
The references are salient attributes. You’re saying the referent doesn’t 
matter because the boundary of the value stops at the reference.  I’m saying it 
does matter in that it means the aggregate is no longer logically isolated 
because shared mutable state is reachable through the aggregate.  Therefore it 
is not isolated in that way that I was intending to describe.  

> 
>> To be honest, I am really struggling to understand why this
>> distinction seems unimportant to you.
> 
> The non-exposure of shared mutable state is a hugely important property
> of well-encapsulated design.  However, I don't believe it's appropriate
> to represent that with a protocol, because I don't believe there exist
> any generic components whose correctness depends on it.

Do you believe it is appropriate to represent this in some other way that 
allows us to state architectural intent and introduce constraints for the 
purpose of structuring a large code base?

> 
> -- 
> -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


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

2016-05-22 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

> On May 22, 2016, at 9:23 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On May 22, 2016, at 1:10 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Mon May 16 2016, Matthew Johnson  wrote:
>> 
 On May 16, 2016, at 1:39 AM, Dave Abrahams  wrote:
 
 
 on Sun May 15 2016, Tyler Fleming Cloutier >>> > wrote:
 
>>> 
>   On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
>   on Mon May 09 2016, Matthew Johnson  wrote:
> 
>   On May 8, 2016, at 1:51 AM, Dave Abrahams  
> wrote:
> 
>   on Sat May 07 2016, Andrew Trick  wrote:
> 
> On May 7, 2016, at 2:04 PM, Dave Abrahams 
>  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 is not a “pure” value (the buffer 
> contained in an
> Array 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 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 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
> 
>   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 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. th

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

2016-05-22 Thread Dave Abrahams via swift-evolution

on Sun May 22 2016, Matthew Johnson  wrote:

> What I am arguing for is the ability to distinguish aggregates which
> are logically isolated from aggregates which contain salient
> references to shared mutable state. 

Everything with value semantics is logically isolated in that way.

> To be honest, I am really struggling to understand why this
> distinction seems unimportant to you.

The non-exposure of shared mutable state is a hugely important property
of well-encapsulated design.  However, I don't believe it's appropriate
to represent that with a protocol, because I don't believe there exist
any generic components whose correctness depends on it.

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-22 Thread Dave Abrahams via swift-evolution

on Sun May 22 2016, Matthew Johnson  wrote:

>> On May 22, 2016, at 12:04 PM, Dave Abrahams via swift-evolution
>>  wrote:
>> 
>> 
>> on Mon May 16 2016, Matthew Johnson  wrote:
>> 
 On May 15, 2016, at 2:01 PM, Dave Abrahams
  wrote:
 
 
 on Fri May 13 2016, Matthew Johnson >>> > wrote:
 
>>> 
> Sent from my iPad
> 
>> On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:
>> 
>> 
>>> on Mon May 09 2016, Matthew Johnson  wrote:
>>> 
>>> My claim is that substituting the constraint of “it has value
>>> semantics,” while presumably looser than the PureValue constraint, would
>>> not compromise the correctness of your view controller, so not only is
>>> the meaning of PureValue hard to define, but it doesn't buy you
>>> anything.  If you want to refute that, just show me the code.
>>> 
>>> This is not an algorithmic use but is still perfectly valid IMO.
>>> 
>>> If the properties of PureValue matter to your view controller, there's
>>> an algorithm somewhere that depends on those properties for its
>>> correctness.
>>> 
>>> In many cases it may just be view configuration that depends on those
>>> properties.  I suppose you can call view configuration code an
>>> algorithm but I think that would fall outside of common usage.
>> It's an algorithm, or if the configuration is declarative, there's
>> an algorithm that manipulates it.  That said, I still don't have a
>> concrete example of how view configuration can depend on these
>> properties.
> The algorithm might just be "copy x bit of data to y view
> property, etc".  That is so trivial that it feels like a stretch to
> call it an algorithm.
 
 Algorithms can be trivial.
>>> 
>>> Fair enough.  Although in most contexts people don’t use the word when
>>> discussing the trivial.
>> 
>> Yes, quite a shame, that.
>> 
> That "algorithm" doesn't depend on this property because it
> executes at a single point in time.  However, a view controller
> might depend on that property in order to render properly across
> time (for example, configuring cells as they scroll on and off
> screen).
 The example is too abstract for me to understand.
 
 Let me put this differently: I recognize that your concept of
 “PureValue” may be a *sufficient* condition for some generic
 algorithm/component to work, but it is never a *necessary*
 condition, because genericity (or use of a superclass or protocol
 type) erases details of the actual types involved from the point of
 view of the algorithm/component.  It doesn't matter if your type
 contains a class reference if it has value semantic properties.  My
 claim is that PureValue is an overly-restrictive constraint that
 makes many things less useful than they should be.
>>> 
>>> In many cases this is true - you don’t need more than value semantics
>>> as you define it.  However it is not at all true that PureValue is
>>> never necessary for the correctness of code.  I’m going to provide an
>>> example to the contrary below.
>>> 
 
> This property allows us to separate values from non-local mutation
> and make such separation a requirement.  Rather than observing
> mutations of objects with KVO, etc we might prefer to observe
> something that provides a new aggregate value instead, while
> requiring the entire aggregate value itself to be (observably)
> immutable at all times (because we stored it with a let property
> locally).  This can make it easier to reason about correct behavior
> of your code.  But it doesn't work unless all visible parts of the
> aggregate are immutable.
> 
> If you're not familiar with Elm, Redux, etc it might be worth
> taking a look.
 That's a pretty broad link.  At which parts do you think I should
 look?
>>> 
>>> The piece that matters here is state management.  The core concept is
>>> to tightly control how mutations happen.  It is modeled in terms of
>>> state type T, an initial value t, an action type A (instances of which
>>> are mutation commands, as in the command pattern), and a reducer
>>> function (T, A) -> T which produces a new state.
>>> 
>>> Here’s a toy implementation that is somewhat simplistic but captures
>>> the essence of the concept:
>>> 
>>> class Store {
>>>typealias Reducer = (State, Action) -> State
>>> 
>>>var stateHistory: [State]
>>>let reducer: Reducer
>>> 
>>>init(initialState: State, reducer: Reducer) {
>>>stateHistory = [initialState]
>>>self.reducer = reducer
>>>}
>>> 
>>>func applyAction(action: Action) {
>>>let newState = reducer(stateHistory.last!, action)
>>>stateHistory.append(newState)
>>>}
>>> 
>>>var currentState: State {
>>>return stateHistory.last!
>>>}
>>> 
>>>var canUndo: Bool {
>>>   

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

2016-05-22 Thread Matthew Johnson via swift-evolution

> On May 22, 2016, at 1:10 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Mon May 16 2016, Matthew Johnson  > wrote:
> 
>>> On May 16, 2016, at 1:39 AM, Dave Abrahams >> > wrote:
>>> 
>>> 
>>> on Sun May 15 2016, Tyler Fleming Cloutier >>  >> >> wrote:
>>> 
>> 
   On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
  wrote:
 
   on Mon May 09 2016, Matthew Johnson  wrote:
 
   On May 8, 2016, at 1:51 AM, Dave Abrahams  
 wrote:
 
   on Sat May 07 2016, Andrew Trick  wrote:
 
 On May 7, 2016, at 2:04 PM, Dave Abrahams 
  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 is not a “pure” value (the buffer 
 contained in an
 Array 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 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 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
 
   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 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 

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

2016-05-22 Thread Matthew Johnson via swift-evolution

> On May 22, 2016, at 12:04 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Mon May 16 2016, Matthew Johnson  wrote:
> 
>>> On May 15, 2016, at 2:01 PM, Dave Abrahams
>>>  wrote:
>>> 
>>> 
>>> on Fri May 13 2016, Matthew Johnson >> > wrote:
>>> 
>> 
 Sent from my iPad
 
> On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:
> 
> 
>> on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>> My claim is that substituting the constraint of “it has value
>> semantics,” while presumably looser than the PureValue constraint, would
>> not compromise the correctness of your view controller, so not only is
>> the meaning of PureValue hard to define, but it doesn't buy you
>> anything.  If you want to refute that, just show me the code.
>> 
>> This is not an algorithmic use but is still perfectly valid IMO.
>> 
>> If the properties of PureValue matter to your view controller, there's
>> an algorithm somewhere that depends on those properties for its
>> correctness.
>> 
>> In many cases it may just be view configuration that depends on those
>> properties.  I suppose you can call view configuration code an
>> algorithm but I think that would fall outside of common usage.
> It's an algorithm, or if the configuration is declarative, there's
> an algorithm that manipulates it.  That said, I still don't have a
> concrete example of how view configuration can depend on these
> properties.
 The algorithm might just be "copy x bit of data to y view
 property, etc".  That is so trivial that it feels like a stretch to
 call it an algorithm.
>>> 
>>> Algorithms can be trivial.
>> 
>> Fair enough.  Although in most contexts people don’t use the word when
>> discussing the trivial.
> 
> Yes, quite a shame, that.
> 
 That "algorithm" doesn't depend on this property because it
 executes at a single point in time.  However, a view controller
 might depend on that property in order to render properly across
 time (for example, configuring cells as they scroll on and off
 screen).
>>> The example is too abstract for me to understand.
>>> 
>>> Let me put this differently: I recognize that your concept of
>>> “PureValue” may be a *sufficient* condition for some generic
>>> algorithm/component to work, but it is never a *necessary*
>>> condition, because genericity (or use of a superclass or protocol
>>> type) erases details of the actual types involved from the point of
>>> view of the algorithm/component.  It doesn't matter if your type
>>> contains a class reference if it has value semantic properties.  My
>>> claim is that PureValue is an overly-restrictive constraint that
>>> makes many things less useful than they should be.
>> 
>> In many cases this is true - you don’t need more than value semantics
>> as you define it.  However it is not at all true that PureValue is
>> never necessary for the correctness of code.  I’m going to provide an
>> example to the contrary below.
>> 
>>> 
 This property allows us to separate values from non-local mutation
 and make such separation a requirement.  Rather than observing
 mutations of objects with KVO, etc we might prefer to observe
 something that provides a new aggregate value instead, while
 requiring the entire aggregate value itself to be (observably)
 immutable at all times (because we stored it with a let property
 locally).  This can make it easier to reason about correct behavior
 of your code.  But it doesn't work unless all visible parts of the
 aggregate are immutable.
 
 If you're not familiar with Elm, Redux, etc it might be worth
 taking a look.
>>> That's a pretty broad link.  At which parts do you think I should
>>> look?
>> 
>> The piece that matters here is state management.  The core concept is
>> to tightly control how mutations happen.  It is modeled in terms of
>> state type T, an initial value t, an action type A (instances of which
>> are mutation commands, as in the command pattern), and a reducer
>> function (T, A) -> T which produces a new state.
>> 
>> Here’s a toy implementation that is somewhat simplistic but captures
>> the essence of the concept:
>> 
>> class Store {
>>typealias Reducer = (State, Action) -> State
>> 
>>var stateHistory: [State]
>>let reducer: Reducer
>> 
>>init(initialState: State, reducer: Reducer) {
>>stateHistory = [initialState]
>>self.reducer = reducer
>>}
>> 
>>func applyAction(action: Action) {
>>let newState = reducer(stateHistory.last!, action)
>>stateHistory.append(newState)
>>}
>> 
>>var currentState: State {
>>return stateHistory.last!
>>}
>> 
>>var canUndo: Bool {
>>return stateHistory.count > 1
>>}
>> 
>>func undo() {
>>if canUndo {
>>stateHistory.popLast()
>>}
>>}
>> }
>> 
>> This 

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

2016-05-22 Thread Dave Abrahams via swift-evolution

on Mon May 16 2016, Matthew Johnson  wrote:

>> On May 16, 2016, at 1:39 AM, Dave Abrahams  wrote:
>> 
>> 
>> on Sun May 15 2016, Tyler Fleming Cloutier > > wrote:
>> 
>
>>>On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>>on Mon May 09 2016, Matthew Johnson  wrote:
>>> 
>>>On May 8, 2016, at 1:51 AM, Dave Abrahams  
>>> wrote:
>>> 
>>>on Sat May 07 2016, Andrew Trick  wrote:
>>> 
>>>  On May 7, 2016, at 2:04 PM, Dave Abrahams 
>>>  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 is not a “pure” value (the buffer 
>>> contained in an
>>>  Array 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 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 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
>>> 
>>>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 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 ca

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

2016-05-22 Thread Dave Abrahams via swift-evolution

on Mon May 16 2016, Matthew Johnson  wrote:

>> On May 15, 2016, at 2:01 PM, Dave Abrahams
>>  wrote:
>> 
>> 
>> on Fri May 13 2016, Matthew Johnson > > wrote:
>> 
>
>>> Sent from my iPad
>>> 
 On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:


> on Mon May 09 2016, Matthew Johnson  wrote:
>
> My claim is that substituting the constraint of “it has value
> semantics,” while presumably looser than the PureValue constraint, would
> not compromise the correctness of your view controller, so not only is
> the meaning of PureValue hard to define, but it doesn't buy you
> anything.  If you want to refute that, just show me the code.
>
> This is not an algorithmic use but is still perfectly valid IMO.
>
> If the properties of PureValue matter to your view controller, there's
> an algorithm somewhere that depends on those properties for its
> correctness.
>
> In many cases it may just be view configuration that depends on those
> properties.  I suppose you can call view configuration code an
> algorithm but I think that would fall outside of common usage.
 It's an algorithm, or if the configuration is declarative, there's
 an algorithm that manipulates it.  That said, I still don't have a
 concrete example of how view configuration can depend on these
 properties.
>>>  The algorithm might just be "copy x bit of data to y view
>>> property, etc".  That is so trivial that it feels like a stretch to
>>> call it an algorithm.
>>
>>  Algorithms can be trivial.
>
> Fair enough.  Although in most contexts people don’t use the word when
> discussing the trivial.

Yes, quite a shame, that.

>>> That "algorithm" doesn't depend on this property because it
>>> executes at a single point in time.  However, a view controller
>>> might depend on that property in order to render properly across
>>> time (for example, configuring cells as they scroll on and off
>>> screen).
>>  The example is too abstract for me to understand.
>> 
>> Let me put this differently: I recognize that your concept of
>> “PureValue” may be a *sufficient* condition for some generic
>> algorithm/component to work, but it is never a *necessary*
>> condition, because genericity (or use of a superclass or protocol
>> type) erases details of the actual types involved from the point of
>> view of the algorithm/component.  It doesn't matter if your type
>> contains a class reference if it has value semantic properties.  My
>> claim is that PureValue is an overly-restrictive constraint that
>> makes many things less useful than they should be.
>
> In many cases this is true - you don’t need more than value semantics
> as you define it.  However it is not at all true that PureValue is
> never necessary for the correctness of code.  I’m going to provide an
> example to the contrary below.
>
>>
>>> This property allows us to separate values from non-local mutation
>>> and make such separation a requirement.  Rather than observing
>>> mutations of objects with KVO, etc we might prefer to observe
>>> something that provides a new aggregate value instead, while
>>> requiring the entire aggregate value itself to be (observably)
>>> immutable at all times (because we stored it with a let property
>>> locally).  This can make it easier to reason about correct behavior
>>> of your code.  But it doesn't work unless all visible parts of the
>>> aggregate are immutable.
>>> 
>>> If you're not familiar with Elm, Redux, etc it might be worth
>>> taking a look.
>>  That's a pretty broad link.  At which parts do you think I should
>> look?
>
> The piece that matters here is state management.  The core concept is
> to tightly control how mutations happen.  It is modeled in terms of
> state type T, an initial value t, an action type A (instances of which
> are mutation commands, as in the command pattern), and a reducer
> function (T, A) -> T which produces a new state.
>
> Here’s a toy implementation that is somewhat simplistic but captures
> the essence of the concept:
>
> class Store {
> typealias Reducer = (State, Action) -> State
> 
> var stateHistory: [State]
> let reducer: Reducer
> 
> init(initialState: State, reducer: Reducer) {
> stateHistory = [initialState]
> self.reducer = reducer
> }
> 
> func applyAction(action: Action) {
> let newState = reducer(stateHistory.last!, action)
> stateHistory.append(newState)
> }
> 
> var currentState: State {
> return stateHistory.last!
> }
> 
> var canUndo: Bool {
> return stateHistory.count > 1
> }
> 
> func undo() {
> if canUndo {
> stateHistory.popLast()
> }
> }
> }
> 
> This design relies on State being a PureValue.  The whole idea is that
> the only way any path of observation rooted at currentState can change
> is when the reducer returns a new state when it is called by
>

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

2016-05-19 Thread Matthew Johnson via swift-evolution

> On May 19, 2016, at 5:07 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Mon May 16 2016, Matthew Johnson  > wrote:
> 
>>> On May 16, 2016, at 10:14 AM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Mon May 16 2016, Matthew Johnson  wrote:
>>> 
>> 
> On May 15, 2016, at 1:53 PM, Dave Abrahams  wrote:
> 
> 
> on Fri May 13 2016, Matthew Johnson  > wrote:
> 
 If we’re going to hide the implementation details maybe it’s worth
 taking advantage of the type by making the props var and using CoW.
 
 What do you think about a proposal to enhance “indirect” for value
 types and / or instances of them.  I can think of a few approaches to
 this that we could consider.  I would be much more comfortable with
 what you want to do if we tackle that as well.
>>> 
>>> It's a good idea that can help to make CoW easy to implement; I have
>>> advocated for it (not in public) in the past.  
>> 
>> Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
>> 
>>> People should be aware
>>> that the resulting automatic CoW will be suboptimal in many cases,
>>> because when you discover you need new storage it's usually better to
>>> build a new value than to copy the old one and overwrite it.
>> 
>> How big a difference does that usually make, especially when compared
>> to the reasons you would use indirect in the first place?  
> 
> Usually a big difference.
> 
>> Wouldn't the compiler be able to do this in the automatic
>> implementation in some cases
> 
> Not in any interesting cases I know of.  If you're inserting into an
> array and you discover you need new storage because there is more than
> one reference, starting by copying can double the cost of the insertion
> (on a large array when memory allocation is fast).
 
 Of course this is true of data structures.  I wouldn’t expect the
 compiler to provide a reasonable implementation of CoW for data
 structures.
 
 Maybe I wasn’t clear.  I was talking about domain model objects like the 
 following:
 
 struct Person {
 var firstName: String
 var lastName: String
 // …
 }
 
 I find it hard to believe the compiler CoW implementation would do
 something so suboptimal as to be significant when you write to
 firstName through an indirect instance in cases like this (which are
 pervasive in application code).
>>> 
>>> Oh, OK.  And you want to CoW this because...?  Reducing refcount
>>> traffic?
>> 
>> Avoiding copying and refcounting.  This might be a large aggregate.
>> You might use indirect structs and CoW so that portions of the
>> aggregate can be shared by more than one aggregate root
>> (i.e. persistent data structure).
> 
> I have no problem with adding some support for doing this manually, but
> IMO the compiler *should* do it automatically for some value types.
> Maybe an attribute could be used to add manual control.

You’re saying when we have support for indirect value types the compiler should 
do it automatically for some of them right?  If that’s what you mean then yes, 
I agree.  The compiler should do it automatically for simple value types (i.e. 
when the right thing is obvious).

> 
> -- 
> -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


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

2016-05-19 Thread Dave Abrahams via swift-evolution

on Mon May 16 2016, Matthew Johnson  wrote:

>> On May 16, 2016, at 10:14 AM, Dave Abrahams  wrote:
>> 
>> 
>> on Mon May 16 2016, Matthew Johnson  wrote:
>> 
>
 On May 15, 2016, at 1:53 PM, Dave Abrahams  wrote:
 
 
 on Fri May 13 2016, Matthew Johnson >>> > wrote:
 
>>> If we’re going to hide the implementation details maybe it’s worth
>>> taking advantage of the type by making the props var and using CoW.
>>> 
>>> What do you think about a proposal to enhance “indirect” for value
>>> types and / or instances of them.  I can think of a few approaches to
>>> this that we could consider.  I would be much more comfortable with
>>> what you want to do if we tackle that as well.
>> 
>> It's a good idea that can help to make CoW easy to implement; I have
>> advocated for it (not in public) in the past.  
> 
> Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
> 
>> People should be aware
>> that the resulting automatic CoW will be suboptimal in many cases,
>> because when you discover you need new storage it's usually better to
>> build a new value than to copy the old one and overwrite it.
> 
> How big a difference does that usually make, especially when compared
> to the reasons you would use indirect in the first place?  
 
 Usually a big difference.
 
> Wouldn't the compiler be able to do this in the automatic
> implementation in some cases
 
 Not in any interesting cases I know of.  If you're inserting into an
 array and you discover you need new storage because there is more than
 one reference, starting by copying can double the cost of the insertion
 (on a large array when memory allocation is fast).
>>> 
>>> Of course this is true of data structures.  I wouldn’t expect the
>>> compiler to provide a reasonable implementation of CoW for data
>>> structures.
>>> 
>>> Maybe I wasn’t clear.  I was talking about domain model objects like the 
>>> following:
>>> 
>>> struct Person {
>>>  var firstName: String
>>>  var lastName: String
>>>  // …
>>> }
>>> 
>>> I find it hard to believe the compiler CoW implementation would do
>>> something so suboptimal as to be significant when you write to
>>> firstName through an indirect instance in cases like this (which are
>>> pervasive in application code).
>> 
>> Oh, OK.  And you want to CoW this because...?  Reducing refcount
>> traffic?
>
> Avoiding copying and refcounting.  This might be a large aggregate.
> You might use indirect structs and CoW so that portions of the
> aggregate can be shared by more than one aggregate root
> (i.e. persistent data structure).

I have no problem with adding some support for doing this manually, but
IMO the compiler *should* do it automatically for some value types.
Maybe an attribute could be used to add manual control.

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Tyler Cloutier via swift-evolution


> On May 16, 2016, at 9:21 AM, Matthew Johnson  wrote:
> 
> 
>>> On May 16, 2016, at 1:17 AM, Tyler Fleming Cloutier  
>>> wrote:
>>> 
>>> 
>>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> on Mon May 09 2016, Matthew Johnson  wrote:
>>> 
> On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Andrew Trick  wrote:
 
>>   On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
>>   Array 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 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 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
> 
> 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 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 

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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 16, 2016, at 1:17 AM, Tyler Fleming Cloutier  
> wrote:
> 
>> 
>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> on Mon May 09 2016, Matthew Johnson > > wrote:
>> 
 On May 8, 2016, at 1:51 AM, Dave Abrahams >>> > wrote:
 
 
 on Sat May 07 2016, Andrew Trick >>> > wrote:
 
>>> 
>   On May 7, 2016, at 2:04 PM, Dave Abrahams  > 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 is not a “pure” value (the buffer contained in an
>   Array 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 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 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
 
 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 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 documentat

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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 16, 2016, at 1:38 AM, Tyler Fleming Cloutier via swift-evolution 
>  wrote:
> 
>> 
>> On May 15, 2016, at 11:17 PM, Tyler Fleming Cloutier via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> on Mon May 09 2016, Matthew Johnson >> > wrote:
>>> 
> On May 8, 2016, at 1:51 AM, Dave Abrahams  > wrote:
> 
> 
> on Sat May 07 2016, Andrew Trick  > wrote:
> 
 
>>   On May 7, 2016, at 2:04 PM, Dave Abrahams > > 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 is not a “pure” value (the buffer contained in an
>>   Array 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 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 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
> 
> 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 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 s

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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 16, 2016, at 1:39 AM, Dave Abrahams  wrote:
> 
> 
> on Sun May 15 2016, Tyler Fleming Cloutier  > wrote:
> 
>>On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>>on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>>On May 8, 2016, at 1:51 AM, Dave Abrahams  
>> wrote:
>> 
>>on Sat May 07 2016, Andrew Trick  wrote:
>> 
>>  On May 7, 2016, at 2:04 PM, Dave Abrahams 
>>  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 is not a “pure” value (the buffer contained 
>> in an
>>  Array 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 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 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
>> 
>>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 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 capac

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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 15, 2016, at 1:48 PM, Dave Abrahams  wrote:
> 
> 
> on Mon May 09 2016, Matthew Johnson  > wrote:
> 
>>> On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Sat May 07 2016, Andrew Trick  wrote:
>>> 
>> 
   On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
   Array 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 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 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
>>> 
>>> 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 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

I asked for your definition of value semantics because you keep asking for a 
concise definition of PureValue.  I was trying to identify how to structure a 
definition in a way that would be acceptable to you.   

> , 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.

Thanks, good talks.  I believe I have seen earlier versions of them previously.

I’m still unsure of what structure would be acceptable to you as John doesn’t 
give a concise “here it is on one slide” definition of the kind you seem to be 
looking for with regards to pure value.  If anything, the talks demonstrate how 
nuanced this discussion is.

That said, I’ll take a shot at defining pure value using John’s terminology.  
John talks about salient attributes quite a bit.  These are the “observable 
parts” I have been talking about.  

John also makes a very strong and clear distinction between “value semantics” 
and “in-core value semantics”.  This distinction is fundamental to the 
distinction I am making.  Your definition of “value semantics” appears to 
include both what John calls “value semantics” as well as what John calls 
“in-core value semantics”.  As far as I can tell my definition of “pure value” 
aligns with what John simply calls “value semantics” (or in some cases he says 
“full value semantics”) which *excludes* what he calls “in-core value 
semantics” (including pointers).  Quoting John:

“What kind of objects do not try to represent a value?  … Pointers actually 
represent something in the middle.  They don’t represent an ethereal type 
because pointers are addresses in a local machine.  Tha

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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 16, 2016, at 10:14 AM, Dave Abrahams  wrote:
> 
> 
> on Mon May 16 2016, Matthew Johnson  wrote:
> 
>>> On May 15, 2016, at 1:53 PM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Fri May 13 2016, Matthew Johnson >> > wrote:
>>> 
>> If we’re going to hide the implementation details maybe it’s worth
>> taking advantage of the type by making the props var and using CoW.
>> 
>> What do you think about a proposal to enhance “indirect” for value
>> types and / or instances of them.  I can think of a few approaches to
>> this that we could consider.  I would be much more comfortable with
>> what you want to do if we tackle that as well.
> 
> It's a good idea that can help to make CoW easy to implement; I have
> advocated for it (not in public) in the past.  
 
 Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
 
> People should be aware
> that the resulting automatic CoW will be suboptimal in many cases,
> because when you discover you need new storage it's usually better to
> build a new value than to copy the old one and overwrite it.
 
 How big a difference does that usually make, especially when compared
 to the reasons you would use indirect in the first place?  
>>> 
>>> Usually a big difference.
>>> 
 Wouldn't the compiler be able to do this in the automatic
 implementation in some cases
>>> 
>>> Not in any interesting cases I know of.  If you're inserting into an
>>> array and you discover you need new storage because there is more than
>>> one reference, starting by copying can double the cost of the insertion
>>> (on a large array when memory allocation is fast).
>> 
>> Of course this is true of data structures.  I wouldn’t expect the
>> compiler to provide a reasonable implementation of CoW for data
>> structures.
>> 
>> Maybe I wasn’t clear.  I was talking about domain model objects like the 
>> following:
>> 
>> struct Person {
>>  var firstName: String
>>  var lastName: String
>>  // …
>> }
>> 
>> I find it hard to believe the compiler CoW implementation would do
>> something so suboptimal as to be significant when you write to
>> firstName through an indirect instance in cases like this (which are
>> pervasive in application code).
> 
> Oh, OK.  And you want to CoW this because...?  Reducing refcount
> traffic?

Avoiding copying and refcounting.  This might be a large aggregate.  You might 
use indirect structs and CoW so that portions of the aggregate can be shared by 
more than one aggregate root (i.e. persistent data structure).

> 
 (such as writing to a stored var)?
>>> 
>>> I don't know what you mean here.
>> 
>> Continuing with the previous example, if the CoW implementation is
>> significantly better when using a memberwise initializer to construct
>> the new box rather than copy the value over from the old box and then
>> update the property that was written to it seems like the compiler
>> should be able to make that optimization in some cases.  (i.e. when
>> there exists a memberwise initializer which exposes all stored
>> properties).
> 
> Sure.
> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 15, 2016, at 2:01 PM, Dave Abrahams  wrote:
> 
> 
> on Fri May 13 2016, Matthew Johnson  > wrote:
> 
>> Sent from my iPad
>> 
>>> On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:
>>> 
>>> 
 on Mon May 09 2016, Matthew Johnson  wrote:
 
   My claim is that substituting the constraint of “it has value
   semantics,” while presumably looser than the PureValue constraint, would
   not compromise the correctness of your view controller, so not only is
   the meaning of PureValue hard to define, but it doesn't buy you
   anything.  If you want to refute that, just show me the code.
 
   This is not an algorithmic use but is still perfectly valid IMO.
 
   If the properties of PureValue matter to your view controller, there's
   an algorithm somewhere that depends on those properties for its
   correctness.
 
 In many cases it may just be view configuration that depends on those
 properties.  I suppose you can call view configuration code an
 algorithm but I think that would fall outside of common usage.
>>> 
>>> It's an algorithm, or if the configuration is declarative, there's an
>>> algorithm that manipulates it.  That said, I still don't have a concrete
>>> example of how view configuration can depend on these properties.
>> 
>> The algorithm might just be "copy x bit of data to y view property,
>> etc".  That is so trivial that it feels like a stretch to call it an
>> algorithm.
> 
> Algorithms can be trivial.

Fair enough.  Although in most contexts people don’t use the word when 
discussing the trivial.

> 
>> That "algorithm" doesn't depend on this property because it executes
>> at a single point in time.  However, a view controller might depend on
>> that property in order to render properly across time (for example,
>> configuring cells as they scroll on and off screen).
> 
> The example is too abstract for me to understand.
> 
> Let me put this differently: I recognize that your concept of
> “PureValue” may be a *sufficient* condition for some generic
> algorithm/component to work, but it is never a *necessary* condition,
> because genericity (or use of a superclass or protocol type) erases
> details of the actual types involved from the point of view of the
> algorithm/component.  It doesn't matter if your type contains a class
> reference if it has value semantic properties.  My claim is that
> PureValue is an overly-restrictive constraint that makes many things
> less useful than they should be.

In many cases this is true - you don’t need more than value semantics as you 
define it.  However it is not at all true that PureValue is never necessary for 
the correctness of code.  I’m going to provide an example to the contrary below.

> 
>> This property allows us to separate values from non-local mutation and
>> make such separation a requirement.  Rather than observing mutations
>> of objects with KVO, etc we might prefer to observe something that
>> provides a new aggregate value instead, while requiring the entire
>> aggregate value itself to be (observably) immutable at all times
>> (because we stored it with a let property locally).  This can make it
>> easier to reason about correct behavior of your code.  But it doesn't
>> work unless all visible parts of the aggregate are immutable.
>> 
>> If you're not familiar with Elm, Redux, etc it might be worth taking
>> a look.  
> 
> That's a pretty broad link.  At which parts do you think I should look?

The piece that matters here is state management.  The core concept is to 
tightly control how mutations happen.  It is modeled in terms of state type T, 
an initial value t, an action type A (instances of which are mutation commands, 
as in the command pattern), and a reducer function (T, A) -> T which produces a 
new state.

Here’s a toy implementation that is somewhat simplistic but captures the 
essence of the concept:

class Store {
typealias Reducer = (State, Action) -> State

var stateHistory: [State]
let reducer: Reducer

init(initialState: State, reducer: Reducer) {
stateHistory = [initialState]
self.reducer = reducer
}

func applyAction(action: Action) {
let newState = reducer(stateHistory.last!, action)
stateHistory.append(newState)
}

var currentState: State {
return stateHistory.last!
}

var canUndo: Bool {
return stateHistory.count > 1
}

func undo() {
if canUndo {
stateHistory.popLast()
}
}
}

This design relies on State being a PureValue.  The whole idea is that the only 
way any path of observation rooted at currentState can change is when the 
reducer returns a new state when it is called by `applyAction`.  That guarantee 
cannot be provided by value semantics alone under your definition of value 
semantics.  Further, each state in the history is intended to be a sta

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

2016-05-16 Thread Tino Heth via swift-evolution
hi there,

just skimmed through the bigger part of this thread — it's a really interesting 
discussion, but wouldn't it be worth a topic on its own?
The title of this message addresses a much simpler question (that imho still 
deserves some answers ;-)

Tino
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Dave Abrahams via swift-evolution

on Mon May 16 2016, Matthew Johnson  wrote:

>> On May 15, 2016, at 1:53 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Fri May 13 2016, Matthew Johnson > > wrote:
>> 
> If we’re going to hide the implementation details maybe it’s worth
> taking advantage of the type by making the props var and using CoW.
> 
> What do you think about a proposal to enhance “indirect” for value
> types and / or instances of them.  I can think of a few approaches to
> this that we could consider.  I would be much more comfortable with
> what you want to do if we tackle that as well.
 
 It's a good idea that can help to make CoW easy to implement; I have
 advocated for it (not in public) in the past.  
>>> 
>>> Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
>>> 
 People should be aware
 that the resulting automatic CoW will be suboptimal in many cases,
 because when you discover you need new storage it's usually better to
 build a new value than to copy the old one and overwrite it.
>>> 
>>> How big a difference does that usually make, especially when compared
>>> to the reasons you would use indirect in the first place?  
>> 
>> Usually a big difference.
>> 
>>> Wouldn't the compiler be able to do this in the automatic
>>> implementation in some cases
>> 
>> Not in any interesting cases I know of.  If you're inserting into an
>> array and you discover you need new storage because there is more than
>> one reference, starting by copying can double the cost of the insertion
>> (on a large array when memory allocation is fast).
>
> Of course this is true of data structures.  I wouldn’t expect the
> compiler to provide a reasonable implementation of CoW for data
> structures.
>
> Maybe I wasn’t clear.  I was talking about domain model objects like the 
> following:
>
> struct Person {
>   var firstName: String
>   var lastName: String
>   // …
> }
>
> I find it hard to believe the compiler CoW implementation would do
> something so suboptimal as to be significant when you write to
> firstName through an indirect instance in cases like this (which are
> pervasive in application code).

Oh, OK.  And you want to CoW this because...?  Reducing refcount
traffic?

>>> (such as writing to a stored var)?
>> 
>> I don't know what you mean here.
>
> Continuing with the previous example, if the CoW implementation is
> significantly better when using a memberwise initializer to construct
> the new box rather than copy the value over from the old box and then
> update the property that was written to it seems like the compiler
> should be able to make that optimization in some cases.  (i.e. when
> there exists a memberwise initializer which exposes all stored
> properties).

Sure.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Matthew Johnson via swift-evolution

> On May 15, 2016, at 1:53 PM, Dave Abrahams  wrote:
> 
> 
> on Fri May 13 2016, Matthew Johnson  > wrote:
> 
>> Sent from my iPad
>> 
>>> On May 13, 2016, at 9:19 AM, Dave Abrahams  wrote:
>>> 
>>> 
 on Mon May 09 2016, Matthew Johnson  wrote:
 
   Remember that the only value semantic reference types are immutable, so
   the struct rendition of such types has only immutable properties.
   Personally, I don't think that transforming
 
  struct X {
...
  private:
let prop1: Type1
let prop2: Type2
let prop2: Type3
  }
 
   into
 
  struct X {
 ...
  private:
class Storage {
  let prop1: Type1
  let prop2: Type2
  let prop2: Type3
}
let value: Storage
  }
 
   is so awful if you find you need to optimize away some reference
   counting manually; you just need to add “.value” to property accesses in
   X's methods, and this doesn't require any forwarding.
 
 It’s not too awful but it does expose implementation details.  
>>> 
>>> How?  All the changes are under “private”
>> 
>> Sorry, I didn't notice private.  Probably because I am thinking of model 
>> types which expose their stored properties.
>> 
 If we’re going to hide the implementation details maybe it’s worth
 taking advantage of the type by making the props var and using CoW.
 
 What do you think about a proposal to enhance “indirect” for value
 types and / or instances of them.  I can think of a few approaches to
 this that we could consider.  I would be much more comfortable with
 what you want to do if we tackle that as well.
>>> 
>>> It's a good idea that can help to make CoW easy to implement; I have
>>> advocated for it (not in public) in the past.  
>> 
>> Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
>> 
>>> People should be aware
>>> that the resulting automatic CoW will be suboptimal in many cases,
>>> because when you discover you need new storage it's usually better to
>>> build a new value than to copy the old one and overwrite it.
>> 
>> How big a difference does that usually make, especially when compared
>> to the reasons you would use indirect in the first place?  
> 
> Usually a big difference.
> 
>> Wouldn't the compiler be able to do this in the automatic
>> implementation in some cases
> 
> Not in any interesting cases I know of.  If you're inserting into an
> array and you discover you need new storage because there is more than
> one reference, starting by copying can double the cost of the insertion
> (on a large array when memory allocation is fast).

Of course this is true of data structures.  I wouldn’t expect the compiler to 
provide a reasonable implementation of CoW for data structures.

Maybe I wasn’t clear.  I was talking about domain model objects like the 
following:

struct Person {
  var firstName: String
  var lastName: String
  // …
}

I find it hard to believe the compiler CoW implementation would do something so 
suboptimal as to be significant when you write to firstName through an indirect 
instance in cases like this (which are pervasive in application code).

> 
>> (such as writing to a stored var)?
> 
> I don't know what you mean here.

Continuing with the previous example, if the CoW implementation is 
significantly better when using a memberwise initializer to construct the new 
box rather than copy the value over from the old box and then update the 
property that was written to it seems like the compiler should be able to make 
that optimization in some cases.  (i.e. when there exists a memberwise 
initializer which exposes all stored properties).

> 
>> Would it be possible to design indirect value types in a way that
>> allows a transition to manual control of CoW without breaking calling
>> code if that becomes necessary?
> 
> Sure, anything is possible in design, and in a feature like this I would
> of course want that capability.  It isn't the right time (for me) to try
> to figure it all out though :-)

Cool.  Not trying to push for it now.  Hopefully it has a chance in Swift 4.

> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Vladimir.S via swift-evolution
FWIW, totally agree with this opinion. I also don't understand why "poor 
beginner who would start typing swift code before reading the manual" 
becomes so important when we decide to accept or not some new feature or 
change. Are we working on language that must be used just to teach 
children/beginners for programming or the main purpose of Swift is 
developing of real(often complex) software products?


Please don't tell me that Swift *can* be used to teach children/beginners, 
I know this, and I believe this is good, and only very basic 
syntax/features will be used for this.


On 16.05.2016 10:46, L. Mihalkovic via swift-evolution wrote:

{bracket}I have watched some of the past discussion in the archive and
noticed a number of situations when good proposals get derailed in the name
of how difficult the syntax would become for the poor beginner who would
start typing swift code before reading the manual. My depiction is a bit
itself of an exageration, but if we all thing about it, I am sure we can
name one such proposal. Programming is not a magical activity that one
should be able to perform without any learning curve, in the name of a
universal intuition guiding us all in the right direction. I would even
wager that the more languages one learns, the easier it becomes to make
wrong assumptions based on how familiar certain patterns or notions
seem{/bracket}

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-16 Thread Tyler Fleming Cloutier via swift-evolution

> On May 16, 2016, at 2:16 AM, Dave Abrahams  wrote:
> 
> 
> on Mon May 16 2016, Tyler Fleming Cloutier  wrote:
> 
 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.
>> 
>> He does pretty frequently. He also refers to them as Mathematical
>> Types. He means the logical type that the C++ implementation is
>> supposed to approximate.
> 
> OK.
> 
>> An example he gives is int and how it only approximates the logical
>> Integer type, because it is represented in many ways, e.g. short, int,
>> long, long long. None of them are exactly the same the logical type.
> 
> Check.
> 
 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.
>> 
>> Swift also goes a lot further with enforcing things like immutability
>> by default with let, particularly for value types. I think that with
>> well defined rules you can go further with what’s enforced, and remove
>> the need for documentation, especially since the distinctions with
>> regards to value types can be subtle.
> 
> Remove the need for documentation! Good luck with that, my friend.
> 
 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 is not a PureValue because it exposes capacity?!  That
>>> sounds crazy to me, since the Array's capacity in no sense has reference
>>> semantics.
>> 
>> I would argue, rather, that capacity for Array *is* a salient
>> attribute, by virtue being public 
> 
> Then you're missing the point.  There would be no point in making the
> distinction “salient” if all public API were salient.  Lakos only
> considers public API.

I’m certainly not missing the point. He is saying that not all public API is 
“salient” because it doesn’t pertain to the logical or ethereal type. I’m 
saying that not everybody will agree on what the ethereal type is, thus they 
will not agree on what is salient.

One what to eliminate the possibility of disagreement is do define the ethereal 
type as what is presented as public API, thus the entire public API is salient. 
No more need for the “salient” distinction, that all goes away.

Whether or not you think this is a good idea is another thing entirely.

> 
>> and that Array is a PureValue by virtue of it not having
>> reference semantics. This I propose is valid, because even though it’s
>> not the most intuitive in this case, it is possible that some
>> algorithm interprets capacity to be salient and relies on two arrays
>> with different capacities being not equal.
>> 
>> I can certainly understand the opposing argument here, but at least
>> this way it is unambiguous.
> 
> Capacity, in Lakos' terms, is non-salient, and that's unambiguous.
> 

“In Lakos’ terms”

I don’t think many people are familiar with Lakos’ terms, and thus it is quite 
ambiguous, that’s kinda my point. What is salient to you is not necessarily 
what is salient to me.

I’m suggesting is that == should have 

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

2016-05-16 Thread Dave Abrahams via swift-evolution

on Mon May 16 2016, Tyler Fleming Cloutier  wrote:

>>> 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.
>
> He does pretty frequently. He also refers to them as Mathematical
> Types. He means the logical type that the C++ implementation is
> supposed to approximate.

OK.

> An example he gives is int and how it only approximates the logical
> Integer type, because it is represented in many ways, e.g. short, int,
> long, long long. None of them are exactly the same the logical type.

Check.

>>> 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.
>
> Swift also goes a lot further with enforcing things like immutability
> by default with let, particularly for value types. I think that with
> well defined rules you can go further with what’s enforced, and remove
> the need for documentation, especially since the distinctions with
> regards to value types can be subtle.

Remove the need for documentation! Good luck with that, my friend.

>>> 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 is not a PureValue because it exposes capacity?!  That
>> sounds crazy to me, since the Array's capacity in no sense has reference
>> semantics.
>
> I would argue, rather, that capacity for Array *is* a salient
> attribute, by virtue being public 

Then you're missing the point.  There would be no point in making the
distinction “salient” if all public API were salient.  Lakos only
considers public API.

> and that Array is a PureValue by virtue of it not having
> reference semantics. This I propose is valid, because even though it’s
> not the most intuitive in this case, it is possible that some
> algorithm interprets capacity to be salient and relies on two arrays
> with different capacities being not equal.
>
> I can certainly understand the opposing argument here, but at least
> this way it is unambiguous.

Capacity, in Lakos' terms, is non-salient, and that's unambiguous.

>>> 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 

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

2016-05-16 Thread Tyler Fleming Cloutier via swift-evolution

> On May 16, 2016, at 12:46 AM, L. Mihalkovic  
> wrote:
> 
> 
> 
> Regards
> (From mobile)
> 
> On May 16, 2016, at 8:17 AM, Tyler Fleming Cloutier via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> on Mon May 09 2016, Matthew Johnson >> > wrote:
>>> 
> On May 8, 2016, at 1:51 AM, Dave Abrahams  > wrote:
> 
> 
> on Sat May 07 2016, Andrew Trick  > wrote:
> 
 
>>   On May 7, 2016, at 2:04 PM, Dave Abrahams > > 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 is not a “pure” value (the buffer contained in an
>>   Array 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 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 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
> 
> 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 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. 
> 
> Yes, it is possible to look at every situation as a pure cross-product of 
> ever single possibility, howev

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

2016-05-16 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

> On May 16, 2016, at 8:39 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
>> on Sun May 15 2016, Tyler Fleming Cloutier  wrote:
>> 
>>On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>>on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>>On May 8, 2016, at 1:51 AM, Dave Abrahams  
>> wrote:
>> 
>>on Sat May 07 2016, Andrew Trick  wrote:
>> 
>>  On May 7, 2016, at 2:04 PM, Dave Abrahams 
>>  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 is not a “pure” value (the buffer contained 
>> in an
>>  Array 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 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 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
>> 
>>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 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

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

2016-05-16 Thread L. Mihalkovic via swift-evolution


Regards
(From mobile)

> On May 16, 2016, at 8:17 AM, Tyler Fleming Cloutier via swift-evolution 
>  wrote:
> 
> 
>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Mon May 09 2016, Matthew Johnson  wrote:
>> 
 On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
 
 
 on Sat May 07 2016, Andrew Trick  wrote:
>>> 
>   On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
>   Array 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 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 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
 
 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 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. 

Yes, it is possible to look at every situation as a pure cross-product of ever 
single possibility, however that is of ten a source of waste as some are all 
clearly associated with a likelyhood of occurance. IMO does does not matter 
that *someone* might (and certainly will) when we can all agree that most would 
not. 

{bracket}I have watched some of the past discussion in the archive and noticed 
a number of situations when good proposals get derailed in the name of how 
difficult the syntax would become for the poor beginner who would start typing 
swift code before reading the manual. My depiction is a

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

2016-05-16 Thread Tyler Fleming Cloutier via swift-evolution

> On May 15, 2016, at 11:39 PM, Dave Abrahams  wrote:
> 
> 
> on Sun May 15 2016, Tyler Fleming Cloutier  wrote:
> 
>>On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>>on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>>On May 8, 2016, at 1:51 AM, Dave Abrahams  
>> wrote:
>> 
>>on Sat May 07 2016, Andrew Trick  wrote:
>> 
>>  On May 7, 2016, at 2:04 PM, Dave Abrahams 
>>  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 is not a “pure” value (the buffer contained 
>> in an
>>  Array 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 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 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
>> 
>>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 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.

He does pretty frequently. He also refers to them as Mathematical Types. He 
means the logical type that the C++ implementation is supposed to approximate.

An example he gives is int and how it only approximates the logical Integer 
type, because it is represented in many ways, e.g. short, int, long, long long. 
None of them are exactly the same the logical type.

> 
>> 
>> 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 

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

2016-05-16 Thread Dave Abrahams via swift-evolution

on Sun May 15 2016, Tyler Fleming Cloutier  wrote:

>> 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.
>
> John refers to this at 52:26 in the first video and mentions that this
> is not full value semantics. 

Huh, maybe I don't agree with him as much as I thought.  But I'll check
it out and see.  Thanks for the reference.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-15 Thread Dave Abrahams via swift-evolution

on Sun May 15 2016, Tyler Fleming Cloutier  wrote:

> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>  wrote:
>
> on Mon May 09 2016, Matthew Johnson  wrote:
>
> On May 8, 2016, at 1:51 AM, Dave Abrahams  
> wrote:
>
> on Sat May 07 2016, Andrew Trick  wrote:
>
>   On May 7, 2016, at 2:04 PM, Dave Abrahams 
>  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 is not a “pure” value (the buffer contained 
> in an
>   Array 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 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 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
>
> 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 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 breakin

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

2016-05-15 Thread Tyler Fleming Cloutier via swift-evolution

> On May 15, 2016, at 11:17 PM, Tyler Fleming Cloutier via swift-evolution 
>  wrote:
> 
>> 
>> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> on Mon May 09 2016, Matthew Johnson > > wrote:
>> 
 On May 8, 2016, at 1:51 AM, Dave Abrahams >>> > wrote:
 
 
 on Sat May 07 2016, Andrew Trick >>> > wrote:
 
>>> 
>   On May 7, 2016, at 2:04 PM, Dave Abrahams  > 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 is not a “pure” value (the buffer contained in an
>   Array 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 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 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
 
 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 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 

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

2016-05-15 Thread Tyler Fleming Cloutier via swift-evolution

> On May 15, 2016, at 11:48 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Mon May 09 2016, Matthew Johnson  > wrote:
> 
>>> On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Sat May 07 2016, Andrew Trick  wrote:
>>> 
>> 
   On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
   Array 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 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 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
>>> 
>>> 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 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 s

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

2016-05-15 Thread Dave Abrahams via swift-evolution

on Fri May 13 2016, Matthew Johnson  wrote:

> Sent from my iPad
>
>> On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:
>> 
>> 
>>> on Mon May 09 2016, Matthew Johnson  wrote:
>>> 
>>>My claim is that substituting the constraint of “it has value
>>>semantics,” while presumably looser than the PureValue constraint, would
>>>not compromise the correctness of your view controller, so not only is
>>>the meaning of PureValue hard to define, but it doesn't buy you
>>>anything.  If you want to refute that, just show me the code.
>>> 
>>>This is not an algorithmic use but is still perfectly valid IMO.
>>> 
>>>If the properties of PureValue matter to your view controller, there's
>>>an algorithm somewhere that depends on those properties for its
>>>correctness.
>>> 
>>> In many cases it may just be view configuration that depends on those
>>> properties.  I suppose you can call view configuration code an
>>> algorithm but I think that would fall outside of common usage.
>> 
>> It's an algorithm, or if the configuration is declarative, there's an
>> algorithm that manipulates it.  That said, I still don't have a concrete
>> example of how view configuration can depend on these properties.
>
> The algorithm might just be "copy x bit of data to y view property,
> etc".  That is so trivial that it feels like a stretch to call it an
> algorithm.

Algorithms can be trivial.

> That "algorithm" doesn't depend on this property because it executes
> at a single point in time.  However, a view controller might depend on
> that property in order to render properly across time (for example,
> configuring cells as they scroll on and off screen).

The example is too abstract for me to understand.

Let me put this differently: I recognize that your concept of
“PureValue” may be a *sufficient* condition for some generic
algorithm/component to work, but it is never a *necessary* condition,
because genericity (or use of a superclass or protocol type) erases
details of the actual types involved from the point of view of the
algorithm/component.  It doesn't matter if your type contains a class
reference if it has value semantic properties.  My claim is that
PureValue is an overly-restrictive constraint that makes many things
less useful than they should be.

> This property allows us to separate values from non-local mutation and
> make such separation a requirement.  Rather than observing mutations
> of objects with KVO, etc we might prefer to observe something that
> provides a new aggregate value instead, while requiring the entire
> aggregate value itself to be (observably) immutable at all times
> (because we stored it with a let property locally).  This can make it
> easier to reason about correct behavior of your code.  But it doesn't
> work unless all visible parts of the aggregate are immutable.
>
>  If you're not familiar with Elm, Redux, etc it might be worth taking
>  a look.  

That's a pretty broad link.  At which parts do you think I should look?

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-15 Thread Dave Abrahams via swift-evolution

on Fri May 13 2016, Matthew Johnson  wrote:

> Sent from my iPad
>
>> On May 13, 2016, at 9:19 AM, Dave Abrahams  wrote:
>> 
>> 
>>> on Mon May 09 2016, Matthew Johnson  wrote:
>>> 
>>>Remember that the only value semantic reference types are immutable, so
>>>the struct rendition of such types has only immutable properties.
>>>Personally, I don't think that transforming
>>> 
>>>   struct X {
>>> ...
>>>   private:
>>> let prop1: Type1
>>> let prop2: Type2
>>> let prop2: Type3
>>>   }
>>> 
>>>into
>>> 
>>>   struct X {
>>>  ...
>>>   private:
>>> class Storage {
>>>   let prop1: Type1
>>>   let prop2: Type2
>>>   let prop2: Type3
>>> }
>>> let value: Storage
>>>   }
>>> 
>>>is so awful if you find you need to optimize away some reference
>>>counting manually; you just need to add “.value” to property accesses in
>>>X's methods, and this doesn't require any forwarding.
>>> 
>>> It’s not too awful but it does expose implementation details.  
>> 
>> How?  All the changes are under “private”
>
> Sorry, I didn't notice private.  Probably because I am thinking of model 
> types which expose their stored properties.
>
>>> If we’re going to hide the implementation details maybe it’s worth
>>> taking advantage of the type by making the props var and using CoW.
>>> 
>>> What do you think about a proposal to enhance “indirect” for value
>>> types and / or instances of them.  I can think of a few approaches to
>>> this that we could consider.  I would be much more comfortable with
>>> what you want to do if we tackle that as well.
>> 
>> It's a good idea that can help to make CoW easy to implement; I have
>> advocated for it (not in public) in the past.  
>
> Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)
>
>> People should be aware
>> that the resulting automatic CoW will be suboptimal in many cases,
>> because when you discover you need new storage it's usually better to
>> build a new value than to copy the old one and overwrite it.
>
> How big a difference does that usually make, especially when compared
> to the reasons you would use indirect in the first place?  

Usually a big difference.

> Wouldn't the compiler be able to do this in the automatic
> implementation in some cases

Not in any interesting cases I know of.  If you're inserting into an
array and you discover you need new storage because there is more than
one reference, starting by copying can double the cost of the insertion
(on a large array when memory allocation is fast).

> (such as writing to a stored var)?

I don't know what you mean here.

> Would it be possible to design indirect value types in a way that
> allows a transition to manual control of CoW without breaking calling
> code if that becomes necessary?

Sure, anything is possible in design, and in a feature like this I would
of course want that capability.  It isn't the right time (for me) to try
to figure it all out though :-)

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-15 Thread Dave Abrahams via swift-evolution

on Mon May 09 2016, Matthew Johnson  wrote:

>> On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
>> 
>> 
>> on Sat May 07 2016, Andrew Trick  wrote:
>> 
>
>>>On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
>>>Array 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 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 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
>> 
>> 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 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.
>
> 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


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

2016-05-13 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 13, 2016, at 9:12 AM, Dave Abrahams  wrote:
> 
> 
>> on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>>My claim is that substituting the constraint of “it has value
>>semantics,” while presumably looser than the PureValue constraint, would
>>not compromise the correctness of your view controller, so not only is
>>the meaning of PureValue hard to define, but it doesn't buy you
>>anything.  If you want to refute that, just show me the code.
>> 
>>This is not an algorithmic use but is still perfectly valid IMO.
>> 
>>If the properties of PureValue matter to your view controller, there's
>>an algorithm somewhere that depends on those properties for its
>>correctness.
>> 
>> In many cases it may just be view configuration that depends on those
>> properties.  I suppose you can call view configuration code an
>> algorithm but I think that would fall outside of common usage.
> 
> It's an algorithm, or if the configuration is declarative, there's an
> algorithm that manipulates it.  That said, I still don't have a concrete
> example of how view configuration can depend on these properties.

The algorithm might just be "copy x bit of data to y view property, etc".  That 
is so trivial that it feels like a stretch to call it an algorithm.

That "algorithm" doesn't depend on this property because it executes at a 
single point in time.  However, a view controller might depend on that property 
in order to render properly across time (for example, configuring cells as they 
scroll on and off screen).  

This property allows us to separate values from non-local mutation and make 
such separation a requirement.  Rather than observing mutations of objects with 
KVO, etc we might prefer to observe something that provides a new aggregate 
value instead, while requiring the entire aggregate value itself to be 
(observably) immutable at all times (because we stored it with a let property 
locally).  This can make it easier to reason about correct behavior of your 
code.  But it doesn't work unless all visible parts of the aggregate are 
immutable.

 If you're not familiar with Elm, Redux, etc it might be worth taking a look.  

> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-13 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 13, 2016, at 9:19 AM, Dave Abrahams  wrote:
> 
> 
>> on Mon May 09 2016, Matthew Johnson  wrote:
>> 
>>Remember that the only value semantic reference types are immutable, so
>>the struct rendition of such types has only immutable properties.
>>Personally, I don't think that transforming
>> 
>>   struct X {
>> ...
>>   private:
>> let prop1: Type1
>> let prop2: Type2
>> let prop2: Type3
>>   }
>> 
>>into
>> 
>>   struct X {
>>  ...
>>   private:
>> class Storage {
>>   let prop1: Type1
>>   let prop2: Type2
>>   let prop2: Type3
>> }
>> let value: Storage
>>   }
>> 
>>is so awful if you find you need to optimize away some reference
>>counting manually; you just need to add “.value” to property accesses in
>>X's methods, and this doesn't require any forwarding.
>> 
>> It’s not too awful but it does expose implementation details.  
> 
> How?  All the changes are under “private”

Sorry, I didn't notice private.  Probably because I am thinking of model types 
which expose their stored properties.

>> If we’re going to hide the implementation details maybe it’s worth
>> taking advantage of the type by making the props var and using CoW.
>> 
>> What do you think about a proposal to enhance “indirect” for value
>> types and / or instances of them.  I can think of a few approaches to
>> this that we could consider.  I would be much more comfortable with
>> what you want to do if we tackle that as well.
> 
> It's a good idea that can help to make CoW easy to implement; I have
> advocated for it (not in public) in the past.  

Glad to hear this.  Maybe in Swift 4?  (I know it's too early to say)

> People should be aware
> that the resulting automatic CoW will be suboptimal in many cases,
> because when you discover you need new storage it's usually better to
> build a new value than to copy the old one and overwrite it.

How big a difference does that usually make, especially when compared to the 
reasons you would use indirect in the first place?  Wouldn't the compiler be 
able to do this in the automatic implementation in some cases (such as writing 
to a stored var)?  Would it be possible to design indirect value types in a way 
that allows a transition to manual control of CoW without breaking calling code 
if that becomes necessary?

> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-13 Thread Dave Abrahams via swift-evolution

on Mon May 09 2016, Matthew Johnson  wrote:

> Remember that the only value semantic reference types are immutable, so
> the struct rendition of such types has only immutable properties.
> Personally, I don't think that transforming
>
>struct X {
>  ...
>private:
>  let prop1: Type1
>  let prop2: Type2
>  let prop2: Type3
>}
>
> into
>
>struct X {
>   ...
>private:
>  class Storage {
>let prop1: Type1
>let prop2: Type2
>let prop2: Type3
>  }
>  let value: Storage
>}
>
> is so awful if you find you need to optimize away some reference
> counting manually; you just need to add “.value” to property accesses in
> X's methods, and this doesn't require any forwarding.
>
> It’s not too awful but it does expose implementation details.  

How?  All the changes are under “private”

> If we’re going to hide the implementation details maybe it’s worth
> taking advantage of the type by making the props var and using CoW.
>
> What do you think about a proposal to enhance “indirect” for value
> types and / or instances of them.  I can think of a few approaches to
> this that we could consider.  I would be much more comfortable with
> what you want to do if we tackle that as well.

It's a good idea that can help to make CoW easy to implement; I have
advocated for it (not in public) in the past.  People should be aware
that the resulting automatic CoW will be suboptimal in many cases,
because when you discover you need new storage it's usually better to
build a new value than to copy the old one and overwrite it.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-13 Thread Dave Abrahams via swift-evolution

on Mon May 09 2016, Matthew Johnson  wrote:

> My claim is that substituting the constraint of “it has value
> semantics,” while presumably looser than the PureValue constraint, would
> not compromise the correctness of your view controller, so not only is
> the meaning of PureValue hard to define, but it doesn't buy you
> anything.  If you want to refute that, just show me the code.
>
> This is not an algorithmic use but is still perfectly valid IMO.
>
> If the properties of PureValue matter to your view controller, there's
> an algorithm somewhere that depends on those properties for its
> correctness.
>
> In many cases it may just be view configuration that depends on those
> properties.  I suppose you can call view configuration code an
> algorithm but I think that would fall outside of common usage.

It's an algorithm, or if the configuration is declarative, there's an
algorithm that manipulates it.  That said, I still don't have a concrete
example of how view configuration can depend on these properties.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-10 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 10, 2016, at 12:53 AM, Andrew Trick  wrote:
> 
> 
>> On May 9, 2016, at 4:07 PM, Matthew Johnson  wrote:
>> 
>> I’m also interested in your feedback on whether a proposal around indirect 
>> is something worth pursuing right now or whether that is something that 
>> should wait until after Swift 3.
> 
> I’m not prepared to champion this for Swift 3, I think there are enough other 
> important proposals on the table, and this is an area that requires careful 
> design.

That's what I suspected and why I asked before taking time to write something 
up.  I'll be patient and look forward to this in the future.

I should add that if a decisions on the changes Dave is looking for must happen 
in Swift 3 or never I support doing it.  While I am concerned about the 
boilerplate I would prefer some boilerplate in the short term to a suboptimal 
design in the long term.

> If I did have to pick features that we touched on in this thread from most to 
> least important I would say:
> 1. Indirect structs
> 2. Mutability of reference/class types
> 3. Automation or annotations for CoW types.
> 4. Annotations that constrain function side effects.

That sounds like the right priorities to me as well. 

> 
> -Andy
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-10 Thread David Sweeris via swift-evolution

> On May 10, 2016, at 00:53, Andrew Trick via swift-evolution 
>  wrote:
> 
> 
>> On May 9, 2016, at 4:07 PM, Matthew Johnson  wrote:
>> 
>> I’m also interested in your feedback on whether a proposal around indirect 
>> is something worth pursuing right now or whether that is something that 
>> should wait until after Swift 3.
> 
> I’m not prepared to champion this for Swift 3, I think there are enough other 
> important proposals on the table, and this is an area that requires careful 
> design. If I did have to pick features that we touched on in this thread from 
> most to least important I would say:
> 1. Indirect structs
> 2. Mutability of reference/class types
> 3. Automation or annotations for CoW types.
> 4. Annotations that constrain function side effects.
> 
> -Andy

Yes, but with possible exception of #2, none of those sound like 
source-breaking changes. I'd imagine that changing what types of properties 
value-types can have will break a few things (although I certainly could be 
wrong).

- Dave Sweeris___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Andrew Trick via swift-evolution

> On May 9, 2016, at 4:07 PM, Matthew Johnson  wrote:
> 
> I’m also interested in your feedback on whether a proposal around indirect is 
> something worth pursuing right now or whether that is something that should 
> wait until after Swift 3.

I’m not prepared to champion this for Swift 3, I think there are enough other 
important proposals on the table, and this is an area that requires careful 
design. If I did have to pick features that we touched on in this thread from 
most to least important I would say:
1. Indirect structs
2. Mutability of reference/class types
3. Automation or annotations for CoW types.
4. Annotations that constrain function side effects.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution

> On May 9, 2016, at 1:03 PM, Andrew Trick  wrote:
> 
> 
>> On May 9, 2016, at 8:34 AM, Matthew Johnson > > wrote:
>> 
>>> I would prefer to wait until indirect structs and improved CoW support have 
>>> had more discussion.
>> 
>> I've been thinking a lot about Dave's desire to "mandate" that value 
>> semantic types must be value types and allowing us to use reference identity 
>> for equality of reference types.  I would support that if these features 
>> were in place so I think shifting to those topics is a good next step for 
>> this discussion.  
>> 
>> Along those lines, I've been thinking about a proposal to allow the indirect 
>> modifier on any property that has a value type.  It may also be useful to 
>> allow the indirect modifier directly on struct and enum to allow type 
>> authors to indicate that all instances should be indirect.  Do you think it 
>> would it be worthwhile to pursue this proposal now?
>> 
>> Can you elaborate on what you have in mind with regards to improved CoW 
>> support?  Is there any chance of doing something here in Swift 3?
> 
> I don’t have anything specific planned for CoW support in Swift 3, otherwise 
> I would have started a separate thread :)

Sure.  I’m still curious about ideas you have for the future.

I’m also interested in your feedback on whether a proposal around indirect is 
something worth pursuing right now or whether that is something that should 
wait until after Swift 3.


> -Andy

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution

> On May 8, 2016, at 1:51 AM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Andrew Trick  wrote:
> 
>>On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
>>Array 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 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 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
> 
> 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 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.  We do not look at unobservable parts because 
we want flexibility to use things like CoW, shared immutable references, etc in 
our implementation.

Can you share your definition of value semantics?  It may be helpful if we 
start there and refine your definition to exclude impure value types like 
Array.

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.



> 
>> At any rate, we could add a PureValue magic protocol, and it would have
>> well-defined meaning. I'm not sure that it is worthwhile or even a good way 
>> to
>> approach the problem. But we don't need to argue about the definition.
> 
> I don't want to argue about anything, really.  I just want a definition.
> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution

> On May 8, 2016, at 1:19 AM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  > wrote:
> 
>>On May 7, 2016, at 4:04 PM, Dave Abrahams  wrote:
>> 
>>on Sat May 07 2016, Matthew Johnson  wrote:
>> 
>>I've been thinking about this further and can now state my position 
>> more
>>clearly
>>and concisely.
>> 
>>1. If we're going to have reference types with value semantics the
>>boundary of
>>the value must extend through the reference to the value of the 
>> object.
>>Two
>>instances may have the same logical value so reference equality is not
>>good
>>enough.
>> 
>>My (radical) position has been that we should decree that if you really
>>want this thing to have value semantics, it should be a struct. That
>>is, wrap your reference type in a struct and provide an == that looks at
>>what's in the instance. This radically simplifies the model because we
>>can then assume that value types have value semantics and reference
>>types only have value semantics if you view their identitity as their
>>value.
>> 
>> I agree with this longer term, but it is too soon for that. 
> 
> We don't have much longer to establish the programming model.  It needs
> to happen soon or it will be too late.
> 
>> Rather than suggest wrapping the reference in a struct I would suggest that 
>> most
>> of the time just making it a struct in the first place is the right
>> path. 
> 
> Well of course.  But if you already have a reference type and aren't
> ready to rewrite it, this is how you do it.
> 
>> The problem with this is that it can lead to excessive copying,
>> reference counting, etc if you’re not careful. I argue that mainstream
>> developers should not need to bother with writing a reference type and
>> wrapping it in a struct just to get around this. 
> 
> Sure, maybe our codegen could be smarter about this, but that shouldn't
> hold back the programming model.
> 
>> It would be nice if there were better, less boilerplate-y solutions to
>> this in the future.
>> 
>>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 is not a “pure” value (the buffer contained in an
>>Array 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.
>> 
>> I have elaborated elsewhere as to why Array does meet my notion of 
>> “pure”
>> value. I understand that it contains a buffer pointer, etc that does not have
>> value semantics. But that is an implementation detail and is not externally
>> observable. I believe that implementation strategies like this are extremely
>> important. I am only concerned with the externally observable semantics and
>> behavior of the type, not the implementation. 
>> 
>> Just as the internal mutable reference type does not disqualify Array 
>> from
>> having value semantics, it also does not disqualify it from being a “pure
>> value".
> 
> As I've indicated, then, you need a different definition than the one
> above.  And you have to get the definition all together in one place so
> it can be evaluated.
> 
>>Purity must include the entire aggregate. Array has value
>>semantics but it is not a pure value.
>> 
>>In what sense does it have value semantics? Unless we can define
>>equality for Array it's hard to make any claim about its value
>>semantics.
>> 
>> Well it should have value semantics using reference equality of the views
>> because UIView has reference semantics so reference identity is the 
>> appropriate
>> definition of equality. Isn’t that your position as well? 
> 
> Yes.  
> 
>>The primary reasons I can think of for creating reference types with
>>value
>>semantics are avoiding copying everything all the time or using
>>inheritance. (I
>>could also list pre-existing types here but am not as concerned with
>>those)
>> 
>>One could argue that you can avoid copying by writing a struct with a
>>handle and
>>one can simulate inheritance by embedding and forwarding. The problem 
>> is
>>that
>>this involves a lot of boilerplate and makes your code more complex. 
>> 
>>The “forwarding boilerplate problem” is something we need to solve in
>>the language regardless. 
>> 
>> Yes I agree that it needs to be solved regardless. In fact, you might 
>> remember
>> that I invested quite a bit of effort into drafting a proposal on the topic. 
>> I
>> shelved it mostly because I became very busy with client work, but also 
>> partly
>> due to the lukewarm reaction.
>> 
>>The fact that we don't have an answer today
>>shouldn't prevent us from adopt

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

2016-05-09 Thread Matthew Johnson via swift-evolution

> On May 8, 2016, at 12:51 AM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  > wrote:
> 
>>> On May 7, 2016, at 3:03 PM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Sat May 07 2016, Matthew Johnson  wrote:
>>> 
 This depends on the type. For types representing resources, etc it works 
 just
 fine. But for models it does not work unless the model subgraph is entirely
 immutable and instances are unique. 
 I agree that it isn't a good idea to provide a default that will
 certainly be wrong in many cases.
>>> 
>>> Please show an example of a mutable model where such an equality would
>>> be wrong.  
>> 
>> This is somewhat orthogonal to the main points I have been making in
>> this thread.  I have been focused on discussion about reference types
>> that have value semantics and the distinction between value semantics
>> and pure values.  In any case, here you go:
>> 
>> let a: NSMutableArray = [1, 2, 3]
>> let other: NSMutableArray = [1, 2, 3]
>> let same = a === other // false
>> let equal = a == other // true
> 
> That's not proof that an == for NSMutableArray that matches the behavior
> of === would be wrong, just that it would be different from what we
> currently have.  
> 
>> Reference equality does not match the behavior of many existing
>> mutable model types.  You seem to be making a case that in Swift it
>> should.  
> 
> Yes.
> 
>> But that is a separate discussion from the one I am trying to engage
>> in because mutable reference types *do not* have value semantics.
> 
> Then maybe I should disengage here?
> 
   Okay then, what algorithms can you write that operate on PureValue 
 that
   don't work equally well on Array?
>>> 
>>> You haven't answered this question.  How would you use this protocol?
>> 
>> I answered elsewhere but I’ll repeat that one use that immediately
>> comes to mind is to constrain values received in the initializer of a
>> (view) controller to ensure that the observable state will not change
>> over time.  
> 
> My claim is that substituting the constraint of “it has value
> semantics,” while presumably looser than the PureValue constraint, would
> not compromise the correctness of your view controller, so not only is
> the meaning of PureValue hard to define, but it doesn't buy you
> anything.  If you want to refute that, just show me the code.
> 
>> This is not an algorithmic use but is still perfectly valid IMO.
> 
> If the properties of PureValue matter to your view controller, there's
> an algorithm somewhere that depends on those properties for its
> correctness.

In many cases it may just be view configuration that depends on those 
properties.  I suppose you can call view configuration code an algorithm but I 
think that would fall outside of common usage.

> 
>> If I read Andrew’s post correctly it sounds like it may also be of use
>> to the optimizer in some cases.
> 
> FWIW, I'm only interested in how you use this protocol in the
> programming model, and I'm not even sure Andrew is talking about the
> same constraint that you are.

I am also primarily interested in the programming model.  That said, as far as 
I can tell everything Andrew has said is talking about the exact same thing I 
am.  Andrew, if I have said anything that doesn’t align with the constraint 
you’re talking about please let me know!

> 
> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution

> On May 8, 2016, at 1:02 AM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  > wrote:
> 
>>> 
>>> You haven't answered this question.  How would you use this protocol?
>> 
>> I think the best example was given by Andy when discussing pure
>> functions.  Maybe I want to write a generic function and ensure it is
>> pure.  I can only do this if I know that any arguments received that
>> compare equal will always present the same observable state.  
> 
> And that it doesn't touch any globals.
> 
>> For example, maybe I wish to memoize the result.
>> 
>> I cannot write such a function for all T, and I also cannot write such
>> a function for all T that have value semantics if we adopt the
>> “references are values” view of the world.  
> 
> Oh, you absolutely can, because if the function applies to all T that
> have value semantics, it only has a few operations to work with:
> initialization, assignment, and equality.  Assignment is the only
> mutating one of these.

I was implicitly assuming additional constraints exposing other behavior.  I 
should have stated that explicitly.

> 
>> I need an additional constraint that rejects things like
>> Array.  (T would obviously also be constrained by a protocol
>> that exposes the properties or methods my function requires to compute
>> its result)
> 
> Did you just start referring to T as the element type of the array
> instead of the function's parameter type?  I think you're
> unintentionally pulling a fast one, reasoning-wise.  It might help to
> write down some actual code.

I was intending to refer to T as the element type of the array all along.  The 
signature I was thinking of would look something like:

pure foo(bar: [T]) -> SomeReturnType

I should have written this down to be clear about it.

> 
>> In general, it would be used where you need to ensure that the result
>> of any operation observing the state of any part of the aggregate
>> value will always return the same value at any point in the future.
>> If I observe a[0].foo now I know with certainty the result of
>> observing a[0].foo at any point in the future.  
> 
> Sure, but what you need then is a constraint on a's Element type that it
> has value semantics, not some kind of new PureValue concept to use as a
> constraint on the array itself.  

That works if you follow all observable paths until you get to scalars.  For 
example maybe A’s element is Array> and `foo ` is implemented in 
an extension off Array where Element == UIVIew (after we get same type 
constraints).  Once we have conditional conformance that extension could 
conform to a protocol that makes `foo` visible and it would still have value 
semantics but it would not be a pure value.

> 
>> This aspect of preservation of observed values across time is
>> essential to the distinction between Array (see below)
>> and Array.  It doesn’t matter when I observe the frames of the
>> elements of Array, I will always get the same rects back.
>> With Array that is obviously not the case as the frame of the
>> view could be mutated by anyone with a reference to the views at any
>> time in between my observations of the frame values.
>> 
>> struct LayoutValue {
>>  frame: CGRect
>> }
>> 
>>> 
   let t = MyClass()
   foo.acceptWrapped(Wrap(t))
   t.mutate()
 
   In this example, foo had better not depend on the wrapped 
 instance
   not
   getting
   mutated.
 
   foo has no way to get at the wrapped instance, so it can't 
 depend on
   anything about it.
 
   Ok, but this is a toy example. What is the purpose of Wrap? Maybe
   foo
   passes the
   wrapped instance back to code that *does* have visibility to the
   instance. My
   point was that shared mutable state is still possible here. 
 
   And my point is that Wrap encapsulates a T (almost—I should 
 have
   let
   it construct the T in its init rather than accepting a T 
 parameter)
   and
   the fact that it's *possible* to code something with the 
 structure
   of
   Wrap so that it has shared mutable state is irrelevant.
 
   The point I am trying to make is that the semantic properties of
   Wrap depend
   on the semantic properties of T (whether or not non-local 
 mutation
   may be
   observed in this case). 
 
   No they do not; Wrap was specifically designed *not* to depend on 
 the
   semantic properties of T. This was in answer to what you said:
 
   A struct wrapping a mutable reference type certainly doesn’t
   “feel” value semantic to me and certainly doesn’t have the
   guarantees usuall

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

2016-05-09 Thread Andrew Trick via swift-evolution

> On May 9, 2016, at 8:34 AM, Matthew Johnson  wrote:
> 
>> I would prefer to wait until indirect structs and improved CoW support have 
>> had more discussion.
> 
> I've been thinking a lot about Dave's desire to "mandate" that value semantic 
> types must be value types and allowing us to use reference identity for 
> equality of reference types.  I would support that if these features were in 
> place so I think shifting to those topics is a good next step for this 
> discussion.  
> 
> Along those lines, I've been thinking about a proposal to allow the indirect 
> modifier on any property that has a value type.  It may also be useful to 
> allow the indirect modifier directly on struct and enum to allow type authors 
> to indicate that all instances should be indirect.  Do you think it would it 
> be worthwhile to pursue this proposal now?
> 
> Can you elaborate on what you have in mind with regards to improved CoW 
> support?  Is there any chance of doing something here in Swift 3?

I don’t have anything specific planned for CoW support in Swift 3, otherwise I 
would have started a separate thread :)
-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 9, 2016, at 3:01 AM, Andrew Trick  wrote:
> 
> 
>>> On May 7, 2016, at 11:51 PM, Dave Abrahams  wrote:
>>> 
>>> Does Array 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 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
>> 
>> only has value semantics if T has value semantics, since SomeConstraint
>> presumably uses aspects of T other than reference identity.  
> 
> I just had a chance to digest Dave's answer. It explains a lot.
> 
> PureValue was defined in terms of the type's physical representation:
> - A struct with no reference properties
> - Recursively, a reference to immutable or uniquely referenced memory.
> 
> It's defined such that we can say Array is a PureValue iff T is a 
> PureValue.
> 
> There is currently no procedure for determining PureValue because we have no 
> way to declare that references are immutable or uniquely referenced. It would 
> be a promise by the developer.
> 
> Now attempting to look at it from Dave's direction, value semantics apply to 
> the variable's type, not the object's physical representation:
> 
> let v2 = v1
> f(v1)
> assert(v1 == v2)
> 
> If everything is a value, then this always works. Great!
> 
> If the variable's type does not allow mutating shared state, then operations 
> on the variable are operating on a value.
> 
> protocol ValueP {
>   func compute() -> Result // nonmutating
> }
> 
> func g(v1 : ValueP) {
>   let v2 = v1
>   v1.compute()
>   assert(v1 == v2)
> }
> 
> Nice. ‘compute' cannot change the value. Those value semantics do not tell me 
> anything about shared state or function purity. For that, I need some 
> additional constraint on 'compute'. Knowing that it does not mutate the 
> 'self' value is insufficient.
> 
> One way of doing that, for example, is to declare that 'compute' transitively 
> cannot access globals *and* ValueP must be a PureValue. Now I can safely 
> write this:
> 
> protocol ValueP : PureValue {
>   @strawman_noglobal func compute() -> Result
> }
> 
> /// Return (v1.compute, v2.compute)
> func g(v1 : ValueP, v2 : ValueP) -> (Result, Result) {
>   let r1 = v1.compute()
>   if v1 == v2 {
> return (r1, r1)
>   }
>   return (r1, v2.compute())
> }
> 
> So, Dave is right that we need to decide soon whether we can make stronger 
> assumptions about value semantics. But that is a separate question from how 
> to express function purity. I don't think there is any urgency in introducing 
> things like the PureValue protocol or @strawman_noglobals attribute, now that 
> we have clearly established shared-state-mutability-by-default. When we want 
> to seriously have that discussion, we should consider other alternatives. I 
> would prefer to wait until indirect structs and improved CoW support have had 
> more discussion.

One more thing that I think we would all agree must come first is some way to 
specify in code that a type has value semantics (whether or not it is pure).  
Is there any ongoing discussion about that?

> 
> -Andy
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-09 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 9, 2016, at 3:01 AM, Andrew Trick  wrote:
> 
> 
>>> On May 7, 2016, at 11:51 PM, Dave Abrahams  wrote:
>>> 
>>> Does Array 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 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
>> 
>> only has value semantics if T has value semantics, since SomeConstraint
>> presumably uses aspects of T other than reference identity.  
> 
> I just had a chance to digest Dave's answer. It explains a lot.
> 
> PureValue was defined in terms of the type's physical representation:
> - A struct with no reference properties
> - Recursively, a reference to immutable or uniquely referenced memory.
> 
> It's defined such that we can say Array is a PureValue iff T is a 
> PureValue.
> 
> There is currently no procedure for determining PureValue because we have no 
> way to declare that references are immutable or uniquely referenced. It would 
> be a promise by the developer.

Yes.  The same can be said of some semantic requirements in existing protocols, 
such as complexity requirements.  It is fair to observe that there is a 
difference here - not meeting complexity requirement slows things down, but 
doesn't fundamentally break.  Another example is the requirement to always 
return nil after you reach the end of IteratorType.

If it is possible to eventually have a mechanism that can be verified by the 
compiler we should wait to introduce the concept until that is in place.  
Verifying value semantics would be the first step in that direction.

> 
> Now attempting to look at it from Dave's direction, value semantics apply to 
> the variable's type, not the object's physical representation:
> 
> let v2 = v1
> f(v1)
> assert(v1 == v2)
> 
> If everything is a value, then this always works. Great!
> 
> If the variable's type does not allow mutating shared state, then operations 
> on the variable are operating on a value.
> 
> protocol ValueP {
>   func compute() -> Result // nonmutating
> }
> 
> func g(v1 : ValueP) {
>   let v2 = v1
>   v1.compute()
>   assert(v1 == v2)
> }
> 
> Nice. ‘compute' cannot change the value. Those value semantics do not tell me 
> anything about shared state or function purity. For that, I need some 
> additional constraint on 'compute'. Knowing that it does not mutate the 
> 'self' value is insufficient.
> 
> One way of doing that, for example, is to declare that 'compute' transitively 
> cannot access globals *and* ValueP must be a PureValue. Now I can safely 
> write this:
> 
> protocol ValueP : PureValue {
>   @strawman_noglobal func compute() -> Result
> }
> 
> /// Return (v1.compute, v2.compute)
> func g(v1 : ValueP, v2 : ValueP) -> (Result, Result) {
>   let r1 = v1.compute()
>   if v1 == v2 {
> return (r1, r1)
>   }
>   return (r1, v2.compute())
> }
> 
> So, Dave is right that we need to decide soon whether we can make stronger 
> assumptions about value semantics. But that is a separate question from how 
> to express function purity.

Agree.  Nailing down value semantics is a big step in the right direction.

> I don't think there is any urgency in introducing things like the PureValue 
> protocol or @strawman_noglobals attribute, now that we have clearly 
> established shared-state-mutability-by-default. When we want to seriously 
> have that discussion, we should consider other alternatives.

No argument from me.  I didn't mean to give a sense of urgency on this and am 
not attached to a specific mechanism.  I am advocating for the importance of 
eventually having a way to distinguish pure values from impure values (even if 
the have value semantics such as Array).  If we don't get there in 
Swift 3 and the solution looks different than a PureValue protocol that is ok 
with me.

> I would prefer to wait until indirect structs and improved CoW support have 
> had more discussion.

I've been thinking a lot about Dave's desire to "mandate" that value semantic 
types must be value types and allowing us to use reference identity for 
equality of reference types.  I would support that if these features were in 
place so I think shifting to those topics is a good next step for this 
discussion.  

Along those lines, I've been thinking about a proposal to allow the indirect 
modifier on any property that has a value type.  It may also be useful to allow 
the indirect modifier directly on struct and enum to allow type authors to 
indicate that all instances should be indirect.  Do you think it would it be 
worthwhile to pursue this proposal now?

Can you elaborate on what you have in mind with regards to improved CoW 

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

2016-05-09 Thread Andrew Trick via swift-evolution

> On May 7, 2016, at 11:51 PM, Dave Abrahams  wrote:
> 
>> Does Array 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 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
> 
> only has value semantics if T has value semantics, since SomeConstraint
> presumably uses aspects of T other than reference identity.  

I just had a chance to digest Dave's answer. It explains a lot.

PureValue was defined in terms of the type's physical representation:
- A struct with no reference properties
- Recursively, a reference to immutable or uniquely referenced memory.

It's defined such that we can say Array is a PureValue iff T is a PureValue.

There is currently no procedure for determining PureValue because we have no 
way to declare that references are immutable or uniquely referenced. It would 
be a promise by the developer.

Now attempting to look at it from Dave's direction, value semantics apply to 
the variable's type, not the object's physical representation:

let v2 = v1
f(v1)
assert(v1 == v2)

If everything is a value, then this always works. Great!

If the variable's type does not allow mutating shared state, then operations on 
the variable are operating on a value.

protocol ValueP {
  func compute() -> Result // nonmutating
}

func g(v1 : ValueP) {
  let v2 = v1
  v1.compute()
  assert(v1 == v2)
}

Nice. ‘compute' cannot change the value. Those value semantics do not tell me 
anything about shared state or function purity. For that, I need some 
additional constraint on 'compute'. Knowing that it does not mutate the 'self' 
value is insufficient.

One way of doing that, for example, is to declare that 'compute' transitively 
cannot access globals *and* ValueP must be a PureValue. Now I can safely write 
this:

protocol ValueP : PureValue {
  @strawman_noglobal func compute() -> Result
}

/// Return (v1.compute, v2.compute)
func g(v1 : ValueP, v2 : ValueP) -> (Result, Result) {
  let r1 = v1.compute()
  if v1 == v2 {
return (r1, r1)
  }
  return (r1, v2.compute())
}

So, Dave is right that we need to decide soon whether we can make stronger 
assumptions about value semantics. But that is a separate question from how to 
express function purity. I don't think there is any urgency in introducing 
things like the PureValue protocol or @strawman_noglobals attribute, now that 
we have clearly established shared-state-mutability-by-default. When we want to 
seriously have that discussion, we should consider other alternatives. I would 
prefer to wait until indirect structs and improved CoW support have had more 
discussion.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-08 Thread Andrew Trick via swift-evolution

> On May 7, 2016, at 6:43 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> If I read Andrew’s post correctly it sounds like it may also be of use to the 
> optimizer in some cases.


I’ll just requote Dave’s example, which made perfect sense to me (so I’m not 
sure why there’s an argument):

> To me that means, if the behavior of “f” only depends on
> data reachable through this array, and f makes no mutations, then in
> this code, the two calls to f() are guaranteed have the same effect.
> 
>  func g(a: [T]) {
>var vc = MyViewController(a)
>vc.f() // #1
>h()
>vc.f() // #2
> }
> 
> But clearly, the only way that can be the case is if T is actually
> immutable (and contains no references to mutable data), because
> otherwise anybody can write:
> 
>class X { ... }
>let global: [X] = [ X() ]
>func h() { global[0].mutatingMethod() }
>g(global)
> 
> Conclusion: your definition of PureValue, as written, implies conforming
> reference types must be immutable.  I'm not saying that's necessarily
> what you meant, but if it isn't, you need to try to define it again.

Yes, of course. If a PureValue contains a reference it must be immutable or 
only mutated when uniquely referenced.

There are other ways to communicate what the optimizer needs. I think the more 
interesting question is how users should express the value semantics of their 
types.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-08 Thread L Mihalkovic via swift-evolution
>>The primary reasons I can think of for creating reference types with
>>value
>>semantics are avoiding copying everything all the time or using
>>inheritance. (I
>>could also list pre-existing types here but am not as concerned with
>>those)
>> 
>>One could argue that you can avoid copying by writing a struct with a
>>handle and
>>one can simulate inheritance by embedding and forwarding. The problem 
>> is
>>that
>>this involves a lot of boilerplate and makes your code more complex. 
>> 
>>The “forwarding boilerplate problem” is something we need to solve in
>>the language regardless. 
>> 
>> Yes I agree that it needs to be solved regardless. In fact, you might 
>> remember
>> that I invested quite a bit of effort into drafting a proposal on the topic. 
>> I
>> shelved it mostly because I became very busy with client work, but also 
>> partly
>> due to the lukewarm reaction.
>> 
>>The fact that we don't have an answer today
>>shouldn't prevent us from adopting the right model for values and
>>references.
>> 
>> I think that depends on what you mean by this. If you mean providing a 
>> default
>> equality of reference identity for reference types I disagree. I think that
>> should wait until the language reaches a place where there is no good reason 
>> to
>> write value semantic reference types. And I believe the boilerplate currently
>> required to wrap them in a struct is sufficiently burdensome that this is not
>> the case yet.
> 
> As I've said, we can't wait.  We should make the change and use that to
> drive development of the necessary features to reduce the burden of
> writing optimized code.  
> 
> Remember that the only value semantic reference types are immutable, so
> the struct rendition of such types has only immutable properties.
> Personally, I don't think that transforming
> 
>struct X {
>  ...
>private:
>  let prop1: Type1
>  let prop2: Type2
>  let prop2: Type3
>}
> 
> into
> 
>struct X {
>   ...
>private:
>  class Storage {
>let prop1: Type1
>let prop2: Type2
>let prop2: Type3
>  }
>  let value: Storage
>}
> 
> is so awful if you find you need to optimize away some reference
> counting manually; you just need to add “.value” to property accesses in
> X's methods, and this doesn't require any forwarding.
> 


FWIW +1. pandora’s box never fully seals back... so it is easier to force 
explicit extra syntax early and later decide that under some special conditions 
the requirements can be relaxed. Considering the timeline for 3.00 as well as 
its associated stake, the aforementioned syntax represents a coherent (if not 
yet fully minimizing of user’s efforts) programing model that could be lived 
with for the foreseeable future, all the while not closing the door on certain 
types of future simplification. 

For example the following syntax is a straw man representation of what could be 
done at a future date to reduce the boilerplate:

   struct X {
 ...
   private:
 @strawman_syntax1 let prop1: Type1
 let prop2: @strawman_syntax2 Type2
 strawman_syntax3 let prop2: Type3
   }

To extend on ‘value semantic reference type’, esthetic considerations would 
push me towards a solution expressing it at the usage site (like in the straw 
man syntax above), rather than via the introduction of a new protocol to be 
used at the definition site. i.e. favoring "my usage here of Type1 instances is 
to be construed as having value semantic” (with the compiler or me crafting a 
different definition of identity) over the less self documenting “Class Type1 
is for all eternity carrying value semantic”, which ultimately seems more 
confusing to me. 
I call it an esthetic argument as it is based on nothing else than a personal 
view on symmetry: (for no good reason) I value symmetry as the sign of a *good* 
design. Struct and Class are structural constructs to express a specific notion 
in the language. Out of my desire for symmetry I would expect that anything 
altering my perception of this notion would have to be equally conveyed within 
the structure of the language. Resorting to protocol compliance to do the same 
strikes me as the kind of deep imbalance I try to avoid.

/LM

>> 
>>So far, I still don't believe that introducing a “pure values”
>>distinction is adding simplicity and clarity. To me it looks like
>>a needless wrinkle.
>> 
>> Fair enough. I suspect that many folks who have been strongly influenced by
>> functional programming may have a different opinion (btw, I don’t mean to 
>> imply
>> anything about the degree to which functional programming has or has not
>> influenced your opinion).
> 
> -- 
> -Dave
> ___
> swift-evolution mailing list

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

2016-05-08 Thread Tyler Fleming Cloutier via swift-evolution

> On May 7, 2016, at 10:39 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Tyler Fleming Cloutier  > wrote:
> 
>>> On May 7, 2016, at 12:52 PM, Dave Abrahams  wrote:
>>> 
>>> 
>>> on Fri May 06 2016, Tyler Fleming Cloutier  wrote:
>>> 
>> 
   On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution
wrote:
 
   on Fri May 06 2016, Matthew Johnson  wrote:
 
   On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
wrote:
 
   Swift’s collections also accomplish this through copying, but only 
 when
   the
   elements they contain also have the same property. 
 
   Only if you think mutable class instances are part of the value of the
   array that stores references to those class instances. As I said
   earlier, you can *take* that point of view, but why would you want to?
   Today, we have left that question wide open, which makes the whole
   notion of what is a logical value very indistinct. I am proposing to
   close it.
 
   On the other hand, it is immediately obvious that non-local mutation
   is quite possibly in the elements of a Swift Array unless
   they are all uniquely referenced.
 
   If you interpret the elements of the array as being *references* to
   objects, there is no possibility of non-local mutation. If you
   interpret the elements as being objects *themselves*, then you've got
   problems.
 
 This does not make sense, because you’ve got problems either way. You are
 arguing, essentially, that everything is a value type because
 references/pointers are a value. 
>>> 
>>> I am arguing that every type can be viewed as a value, allowing us to
>>> preserve a sense in which Array has value semantics irrespective of
>>> the details of T.
>>> 
 If that were the case then the *only* valid way to compare the
 equality of types would be to compare their values. Overriding the
 equality operator would inherently violate the property of
 immutability, i.e. two immutable objects can change their equality
 even without mutation of their “values".
>>> 
>>> Not at all.  In my world, you can override equality such that it
>>> includes referenced storage when either:
>>> 
>>> 1. the referenced storage will not be mutated
>>> 2. or, the referenced storage will only mutated when uniquely-referenced.
>>> 
 
 func ==(lhs, rhs) {
 ...
 }
 
 class MyClass {
 var a: Int
 ...
 
 } 
 
 let x = MyClass(a: 5)
 let y = MyClass(a: 5)
 
 x == y // true
 y.a = 6
 x == y // false
>>> 
>>> I don't understand what point you're trying to make, here.  I see that x
>>> and y are immutable. Notwithstanding the fact that the language tries to
>>> hide the difference between a reference and the instance to which it
>>> refers from the user (the difference would be clearer if you had to
>>> write y->a = 6 as in C, but it's still there), that immutability doesn't
>>> extend beyond the variable binding.  The class instance to which y
>>> refers, as you've ably demonstrated, is mutable.
>> 
>> The point I’m trying to make is that in the above code, I am able to
>> violate rule 1 of your world insofar as I am including referenced
>> storage in my definition of equality which can be mutated even though
>> my reference is immutable.
> 
> Sorry, I guess I don't understand what difference it makes that it's
> possible to write code that violates my rules.  It's not news to me, as
> I'm sure you knew when you posted it.
> 
   Are you arguing that reference types should be equatable by default,
   using
   equality of the reference if the type does not provide a custom
   definition of
   equality?
 
   Yes!!
 
 Custom definitions of equality, inherently, decouple immutability from
 equality,
>>> 
>>> Not a bit.  They certainly *can* do that, if we allow it, but I am
>>> proposing to ban that.  There are still useful custom definitions of
>>> equality as I have outlined above.
>> 
>> If you’re proposing to ban that, then I may have misunderstood your
>> position. I think we are in agreement on that, however… (more below)
>> 
>>> 
 as shown above. Swift makes it appear as though references and values
 are on the same level in a way that C does not.
>>> 
>>> Yep.  It's an illusion that breaks down at the edges and can be really
>>> problematic if users fully embrace it.  You can't write a generic
>>> algorithm with well-defined semantics that does mutation-by-part on
>>> instances of T without constraining T to have value or reference semantics.
>>> 
>>> I am not advocating that we require “y->a” for class member access, but
>>> I *am* suggesting that we should accept the fact that reference and
>>> value semantics are fundamentally different and make design choices
>>> (including languag

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Andrew Trick  wrote:

> On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
> Array 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 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 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

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 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.

> At any rate, we could add a PureValue magic protocol, and it would have
> well-defined meaning. I'm not sure that it is worthwhile or even a good way to
> approach the problem. But we don't need to argue about the definition.

I don't want to argue about anything, really.  I just want a definition.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

> On May 7, 2016, at 4:04 PM, Dave Abrahams  wrote:
>
> on Sat May 07 2016, Matthew Johnson  wrote:
>
> I've been thinking about this further and can now state my position 
> more
> clearly
> and concisely.
>
> 1. If we're going to have reference types with value semantics the
> boundary of
> the value must extend through the reference to the value of the 
> object.
> Two
> instances may have the same logical value so reference equality is not
> good
> enough.
>
> My (radical) position has been that we should decree that if you really
> want this thing to have value semantics, it should be a struct. That
> is, wrap your reference type in a struct and provide an == that looks at
> what's in the instance. This radically simplifies the model because we
> can then assume that value types have value semantics and reference
> types only have value semantics if you view their identitity as their
> value.
>
> I agree with this longer term, but it is too soon for that. 

We don't have much longer to establish the programming model.  It needs
to happen soon or it will be too late.

> Rather than suggest wrapping the reference in a struct I would suggest that 
> most
> of the time just making it a struct in the first place is the right
> path. 

Well of course.  But if you already have a reference type and aren't
ready to rewrite it, this is how you do it.

> The problem with this is that it can lead to excessive copying,
> reference counting, etc if you’re not careful. I argue that mainstream
> developers should not need to bother with writing a reference type and
> wrapping it in a struct just to get around this. 

Sure, maybe our codegen could be smarter about this, but that shouldn't
hold back the programming model.

> It would be nice if there were better, less boilerplate-y solutions to
> this in the future.
>
> 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 is not a “pure” value (the buffer contained in an
> Array 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.
>
> I have elaborated elsewhere as to why Array does meet my notion of “pure”
> value. I understand that it contains a buffer pointer, etc that does not have
> value semantics. But that is an implementation detail and is not externally
> observable. I believe that implementation strategies like this are extremely
> important. I am only concerned with the externally observable semantics and
> behavior of the type, not the implementation. 
>
> Just as the internal mutable reference type does not disqualify Array 
> from
> having value semantics, it also does not disqualify it from being a “pure
> value".

As I've indicated, then, you need a different definition than the one
above.  And you have to get the definition all together in one place so
it can be evaluated.

> Purity must include the entire aggregate. Array has value
> semantics but it is not a pure value.
>
> In what sense does it have value semantics? Unless we can define
> equality for Array it's hard to make any claim about its value
> semantics.
>
> Well it should have value semantics using reference equality of the views
> because UIView has reference semantics so reference identity is the 
> appropriate
> definition of equality. Isn’t that your position as well? 

Yes.  

> The primary reasons I can think of for creating reference types with
> value
> semantics are avoiding copying everything all the time or using
> inheritance. (I
> could also list pre-existing types here but am not as concerned with
> those)
>
> One could argue that you can avoid copying by writing a struct with a
> handle and
> one can simulate inheritance by embedding and forwarding. The problem 
> is
> that
> this involves a lot of boilerplate and makes your code more complex. 
>
> The “forwarding boilerplate problem” is something we need to solve in
> the language regardless. 
>
> Yes I agree that it needs to be solved regardless. In fact, you might remember
> that I invested quite a bit of effort into drafting a proposal on the topic. I
> shelved it mostly because I became very busy with client work, but also partly
> due to the lukewarm reaction.
>
> The fact that we don't have an answer today
> shouldn't prevent us from adopting the right model for values and
> references.
>
> I think that depends on what you mean by this. If you mean providing a default
> equality of reference identity for reference types I disagree. I think that
> s

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

>> 
>> You haven't answered this question.  How would you use this protocol?
>
> I think the best example was given by Andy when discussing pure
> functions.  Maybe I want to write a generic function and ensure it is
> pure.  I can only do this if I know that any arguments received that
> compare equal will always present the same observable state.  

And that it doesn't touch any globals.

> For example, maybe I wish to memoize the result.
>
> I cannot write such a function for all T, and I also cannot write such
> a function for all T that have value semantics if we adopt the
> “references are values” view of the world.  

Oh, you absolutely can, because if the function applies to all T that
have value semantics, it only has a few operations to work with:
initialization, assignment, and equality.  Assignment is the only
mutating one of these.

> I need an additional constraint that rejects things like
> Array.  (T would obviously also be constrained by a protocol
> that exposes the properties or methods my function requires to compute
> its result)

Did you just start referring to T as the element type of the array
instead of the function's parameter type?  I think you're
unintentionally pulling a fast one, reasoning-wise.  It might help to
write down some actual code.

> In general, it would be used where you need to ensure that the result
> of any operation observing the state of any part of the aggregate
> value will always return the same value at any point in the future.
> If I observe a[0].foo now I know with certainty the result of
> observing a[0].foo at any point in the future.  

Sure, but what you need then is a constraint on a's Element type that it
has value semantics, not some kind of new PureValue concept to use as a
constraint on the array itself.  

> This aspect of preservation of observed values across time is
> essential to the distinction between Array (see below)
> and Array.  It doesn’t matter when I observe the frames of the
> elements of Array, I will always get the same rects back.
> With Array that is obviously not the case as the frame of the
> view could be mutated by anyone with a reference to the views at any
> time in between my observations of the frame values.
>
> struct LayoutValue {
>   frame: CGRect
> }
>
>> 
>>>let t = MyClass()
>>>foo.acceptWrapped(Wrap(t))
>>>t.mutate()
>>> 
>>>In this example, foo had better not depend on the wrapped 
>>> instance
>>>not
>>>getting
>>>mutated.
>>> 
>>>foo has no way to get at the wrapped instance, so it can't 
>>> depend on
>>>anything about it.
>>> 
>>>Ok, but this is a toy example. What is the purpose of Wrap? Maybe
>>>foo
>>>passes the
>>>wrapped instance back to code that *does* have visibility to the
>>>instance. My
>>>point was that shared mutable state is still possible here. 
>>> 
>>>And my point is that Wrap encapsulates a T (almost—I should 
>>> have
>>>let
>>>it construct the T in its init rather than accepting a T 
>>> parameter)
>>>and
>>>the fact that it's *possible* to code something with the 
>>> structure
>>>of
>>>Wrap so that it has shared mutable state is irrelevant.
>>> 
>>>The point I am trying to make is that the semantic properties of
>>>Wrap depend
>>>on the semantic properties of T (whether or not non-local 
>>> mutation
>>>may be
>>>observed in this case). 
>>> 
>>>No they do not; Wrap was specifically designed *not* to depend on 
>>> the
>>>semantic properties of T. This was in answer to what you said:
>>> 
>>>A struct wrapping a mutable reference type certainly doesn’t
>>>“feel” value semantic to me and certainly doesn’t have the
>>>guarantees usually associated with value semantics (won’t
>>>mutate behind your back, thread safe, etc).
>>> 
>>>I have been trying to get you to nail down what you mean by 
>>> PureValue,
>>>and I was trying to illustrate that merely being “a struct wrapping a
>>>mutable reference type” is not enough to disqualify anything from 
>>> being
>>>in the category you're trying to describe. What are the properties of
>>>types in that category, and what generic code would depend on those
>>>properties?
>> 
>> Again, the key questions are above, asked a different way.
>> 
>> -- 
>> -Dave

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

>> On May 7, 2016, at 3:03 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Sat May 07 2016, Matthew Johnson  wrote:
>> 
>>> This depends on the type. For types representing resources, etc it works 
>>> just
>>> fine. But for models it does not work unless the model subgraph is entirely
>>> immutable and instances are unique. 
>>> I agree that it isn't a good idea to provide a default that will
>>> certainly be wrong in many cases.
>> 
>> Please show an example of a mutable model where such an equality would
>> be wrong.  
>
> This is somewhat orthogonal to the main points I have been making in
> this thread.  I have been focused on discussion about reference types
> that have value semantics and the distinction between value semantics
> and pure values.  In any case, here you go:
>
> let a: NSMutableArray = [1, 2, 3]
> let other: NSMutableArray = [1, 2, 3]
> let same = a === other // false
> let equal = a == other // true

That's not proof that an == for NSMutableArray that matches the behavior
of === would be wrong, just that it would be different from what we
currently have.  

> Reference equality does not match the behavior of many existing
> mutable model types.  You seem to be making a case that in Swift it
> should.  

Yes.

> But that is a separate discussion from the one I am trying to engage
> in because mutable reference types *do not* have value semantics.

Then maybe I should disengage here?

>>>Okay then, what algorithms can you write that operate on PureValue 
>>> that
>>>don't work equally well on Array?
>> 
>> You haven't answered this question.  How would you use this protocol?
>
> I answered elsewhere but I’ll repeat that one use that immediately
> comes to mind is to constrain values received in the initializer of a
> (view) controller to ensure that the observable state will not change
> over time.  

My claim is that substituting the constraint of “it has value
semantics,” while presumably looser than the PureValue constraint, would
not compromise the correctness of your view controller, so not only is
the meaning of PureValue hard to define, but it doesn't buy you
anything.  If you want to refute that, just show me the code.

> This is not an algorithmic use but is still perfectly valid IMO.

If the properties of PureValue matter to your view controller, there's
an algorithm somewhere that depends on those properties for its
correctness.

> If I read Andrew’s post correctly it sounds like it may also be of use
> to the optimizer in some cases.

FWIW, I'm only interested in how you use this protocol in the
programming model, and I'm not even sure Andrew is talking about the
same constraint that you are.


-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Tyler Fleming Cloutier  wrote:

>> On May 7, 2016, at 12:52 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Fri May 06 2016, Tyler Fleming Cloutier  wrote:
>> 
>
>>>On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Fri May 06 2016, Matthew Johnson  wrote:
>>> 
>>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>Swift’s collections also accomplish this through copying, but only 
>>> when
>>>the
>>>elements they contain also have the same property. 
>>> 
>>>Only if you think mutable class instances are part of the value of the
>>>array that stores references to those class instances. As I said
>>>earlier, you can *take* that point of view, but why would you want to?
>>>Today, we have left that question wide open, which makes the whole
>>>notion of what is a logical value very indistinct. I am proposing to
>>>close it.
>>> 
>>>On the other hand, it is immediately obvious that non-local mutation
>>>is quite possibly in the elements of a Swift Array unless
>>>they are all uniquely referenced.
>>> 
>>>If you interpret the elements of the array as being *references* to
>>>objects, there is no possibility of non-local mutation. If you
>>>interpret the elements as being objects *themselves*, then you've got
>>>problems.
>>> 
>>> This does not make sense, because you’ve got problems either way. You are
>>> arguing, essentially, that everything is a value type because
>>> references/pointers are a value. 
>> 
>> I am arguing that every type can be viewed as a value, allowing us to
>> preserve a sense in which Array has value semantics irrespective of
>> the details of T.
>> 
>>> If that were the case then the *only* valid way to compare the
>>> equality of types would be to compare their values. Overriding the
>>> equality operator would inherently violate the property of
>>> immutability, i.e. two immutable objects can change their equality
>>> even without mutation of their “values".
>> 
>> Not at all.  In my world, you can override equality such that it
>> includes referenced storage when either:
>> 
>> 1. the referenced storage will not be mutated
>> 2. or, the referenced storage will only mutated when uniquely-referenced.
>> 
>>> 
>>> func ==(lhs, rhs) {
>>> ...
>>> }
>>> 
>>> class MyClass {
>>> var a: Int
>>> ...
>>> 
>>> } 
>>> 
>>> let x = MyClass(a: 5)
>>> let y = MyClass(a: 5)
>>> 
>>> x == y // true
>>> y.a = 6
>>> x == y // false
>> 
>> I don't understand what point you're trying to make, here.  I see that x
>> and y are immutable. Notwithstanding the fact that the language tries to
>> hide the difference between a reference and the instance to which it
>> refers from the user (the difference would be clearer if you had to
>> write y->a = 6 as in C, but it's still there), that immutability doesn't
>> extend beyond the variable binding.  The class instance to which y
>> refers, as you've ably demonstrated, is mutable.
>
> The point I’m trying to make is that in the above code, I am able to
> violate rule 1 of your world insofar as I am including referenced
> storage in my definition of equality which can be mutated even though
> my reference is immutable.

Sorry, I guess I don't understand what difference it makes that it's
possible to write code that violates my rules.  It's not news to me, as
I'm sure you knew when you posted it.

>>>Are you arguing that reference types should be equatable by default,
>>>using
>>>equality of the reference if the type does not provide a custom
>>>definition of
>>>equality?
>>> 
>>>Yes!!
>>> 
>>> Custom definitions of equality, inherently, decouple immutability from
>>> equality,
>> 
>> Not a bit.  They certainly *can* do that, if we allow it, but I am
>> proposing to ban that.  There are still useful custom definitions of
>> equality as I have outlined above.
>
> If you’re proposing to ban that, then I may have misunderstood your
> position. I think we are in agreement on that, however… (more below)
>
>> 
>>> as shown above. Swift makes it appear as though references and values
>>> are on the same level in a way that C does not.
>> 
>> Yep.  It's an illusion that breaks down at the edges and can be really
>> problematic if users fully embrace it.  You can't write a generic
>> algorithm with well-defined semantics that does mutation-by-part on
>> instances of T without constraining T to have value or reference semantics.
>> 
>> I am not advocating that we require “y->a” for class member access, but
>> I *am* suggesting that we should accept the fact that reference and
>> value semantics are fundamentally different and make design choices
>> (including language rules) accordingly.
>> 
>>> let x = MyStruct()
>>> let y = MyClass()
>>> 
>>> x.myFoo
>>> y.myFoo
>>> 
>>> vs
>>> 
>>> my_struct *x = …
>>> my_struct y = …
>>> 
>>> x.my_foo
>>> y->my_foo
>>> 
>>> Wit

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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 7:07 PM, Andrew Trick  wrote:
> 
> 
>> On May 7, 2016, at 2:04 PM, Dave Abrahams > > 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 is not a “pure” value (the buffer contained in an
>> Array 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. Does Array have value semantics then only 
> if T also has value semantics?
> 
> 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. That 
> fact is what allows the compiler to ignore mutation of the buffer.
> 
> It's perfectly clear that Array is a PureValue iff T is a PureValue. 
> PureValue is nothing more than transitive value semantics.
> 
> At any rate, we could add a PureValue magic protocol, and it would have 
> well-defined meaning. I'm not sure that it is worthwhile or even a good way 
> to approach the problem. But we don't need to argue about the definition.

Thanks for jumping in again.  I hope we can get past the discussion of 
definition!

Are you speaking specifically about this being of use to the optimizer or about 
the value of such a protocol in general?

For example, if we introduce a notion of pure functions into the language 
wouldn’t it be useful to be able to write generic pure functions by 
constraining the argument types to PureValue?

IMO this property is important enough that the ability to express it directly 
in code (rather than documentation) and to take advantage of it in generic code 
is very desirable.  A PureValue protocol seems like a good way to do this but I 
am certainly open to other solutions as well.  

Long term it would be really nice if Swift had a logically pure subset and the 
ability to clearly distinguish code that lives inside that world from code that 
is outside that world.  I say “logically" pure because I think implementation 
techniques like CoW, memoization, etc are very valuable and do not violate the 
spirit of purity despite the fact that they rely on side effects.

-Matthew

> 
> -Andy

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 3:03 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  wrote:
> 
>> This depends on the type. For types representing resources, etc it works just
>> fine. But for models it does not work unless the model subgraph is entirely
>> immutable and instances are unique. 
>> I agree that it isn't a good idea to provide a default that will
>> certainly be wrong in many cases.
> 
> Please show an example of a mutable model where such an equality would
> be wrong.  

Maybe wrong is a little bit too strong a word, but it certainly isn’t the 
behavior people are accustomed to.  I think most people consider model 
instances to be logically equal if their properties are equal regardless of the 
address of the instances in memory.  Reference identity only works as expected 
if the model instances are uniqued in memory.  

let a: NSMutableArray = [1, 2, 3]
let b: NSMutableArray = [1, 2, 3]

let referenceEquality = a === b  // false
let elementEquality = a == b  // true


> 
>>I assume what is meant by "PureValue", is any object A, whose own 
>> references
>>form a subgraph, within which a change to any of the values would 
>> constitute
>>a change in the value of A (thus impermissible if A is immutable). Thus
>>structs would quality as “PureValues”.
>> 
>> As you noted in a followup, not all structs qualify. Structs that whose 
>> members
>> all qualify will qualify. References to a subgraph that doesn't allow for any
>> observable mutation (i.e. deeply immutable reference types) also qualify.
>> 
>> This means the following qualify:
>> 
>> * primitive structs and enums
>> * observable immutable object subgraphs
>> * any type composed from the previous
>> 
>> It follows that generic types often conditionally qualify depending on their
>> type arguments.
>> 
>>I also assume that enforcing immutability on an object graph, via CoW or
>>otherwise, would be unfeasible. You could enforce it on all values
>>accessible by traversing a single reference for reference types, however.
>> 
>>This is why I don’t really buy the argument that there is no such this as
>>deep vs shallow copy. Deep copy means copying the whole “PureValue” or
>>subgraph, shallow copy means traversing a single reference and copying all
>>accessible values.
>> 
>>I don’t mean to imply that it is the *only* valuable
>>property. However, it I (and many others) do believe it is an
>>extremely
>>valuable
>>property in many cases. Do you disagree?
>> 
>>I think I do. What is valuable about such a protocol? What generic
>>algorithms could you write that work on models of PureValue but
>>don't
>>work just as well on Array?
>> 
>>Array provides the semantics I have in mind just fine so 
>> there
>>wouldn’t be
>>any. Array is a completely different story. With
>>Array you cannot rely on a guarantee the objects
>>contained
>>in the array will not be mutated by code elsewhere that also 
>> happens
>>to have a reference to the same objects.
>> 
>>Okay then, what algorithms can you write that operate on PureValue 
>> that
>>don't work equally well on Array?
> 
> You haven't answered this question.  How would you use this protocol?

I think the best example was given by Andy when discussing pure functions.  
Maybe I want to write a generic function and ensure it is pure.  I can only do 
this if I know that any arguments received that compare equal will always 
present the same observable state.  For example, maybe I wish to memoize the 
result.  

I cannot write such a function for all T, and I also cannot write such a 
function for all T that have value semantics if we adopt the “references are 
values” view of the world.  I need an additional constraint that rejects things 
like Array.  (T would obviously also be constrained by a protocol that 
exposes the properties or methods my function requires to compute its result)

In general, it would be used where you need to ensure that the result of any 
operation observing the state of any part of the aggregate value will always 
return the same value at any point in the future.  If I observe a[0].foo now I 
know with certainty the result of observing a[0].foo at any point in the 
future.  This aspect of preservation of observed values across time is 
essential to the distinction between Array (see below) and 
Array.  It doesn’t matter when I observe the frames of the elements of 
Array, I will always get the same rects back.  With Array 
that is obviously not the case as the frame of the view could be mutated by 
anyone with a reference to the views at any time in between my observations of 
the frame values.

struct LayoutValue {
frame: CGRect
}


> 
>>let t = MyClass()
>>foo.acceptWrapped(Wrap(t)

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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 4:04 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  > wrote:
> 
>> I've been thinking about this further and can now state my position more 
>> clearly
>> and concisely.
>> 
>> 1. If we're going to have reference types with value semantics the boundary 
>> of
>> the value must extend through the reference to the value of the object. Two
>> instances may have the same logical value so reference equality is not good
>> enough.
> 
> My (radical) position has been that we should decree that if you really
> want this thing to have value semantics, it should be a struct.  That
> is, wrap your reference type in a struct and provide an == that looks at
> what's in the instance.  This radically simplifies the model because we
> can then assume that value types have value semantics and reference
> types only have value semantics if you view their identitity as their
> value.

I agree with this longer term, but it is too soon for that.  

Rather than suggest wrapping the reference in a struct I would suggest that 
most of the time just making it a struct in the first place is the right path.  
The problem with this is that it can lead to excessive copying, reference 
counting, etc if you’re not careful.  I argue that mainstream developers should 
not need to bother with writing a reference type and wrapping it in a struct 
just to get around this.  It would be nice if there were better, less 
boilerplate-y solutions to this in the future.  

> 
>> 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 is not a “pure” value (the buffer contained in an
> Array 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.

I have elaborated elsewhere as to why Array does meet my notion of “pure” 
value.  I understand that it contains a buffer pointer, etc that does not have 
value semantics.  But that is an implementation detail and is not externally 
observable.  I believe that implementation strategies like this are extremely 
important.  I am only concerned with the externally observable semantics and 
behavior of the type, not the implementation.  

Just as the internal mutable reference type does not disqualify Array from 
having value semantics, it also does not disqualify it from being a “pure 
value".

> 
>> Purity must include the entire aggregate. Array has value
>> semantics but it is not a pure value.
> 
> In what sense does it have value semantics?  Unless we can define
> equality for Array it's hard to make any claim about its value
> semantics.

Well it should have value semantics using reference equality of the views 
because UIView has reference semantics so reference identity is the appropriate 
definition of equality.  Isn’t that your position as well? 

> 
>> The primary reasons I can think of for creating reference types with value
>> semantics are avoiding copying everything all the time or using inheritance. 
>> (I
>> could also list pre-existing types here but am not as concerned with those)
>> 
>> One could argue that you can avoid copying by writing a struct with a handle 
>> and
>> one can simulate inheritance by embedding and forwarding. The problem is that
>> this involves a lot of boilerplate and makes your code more complex. 
> 
> The “forwarding boilerplate problem” is something we need to solve in
> the language regardless.  

Yes I agree that it needs to be solved regardless.  In fact, you might remember 
that I invested quite a bit of effort into drafting a proposal on the topic.  I 
shelved it mostly because I became very busy with client work, but also partly 
due to the lukewarm reaction.

> The fact that we don't have an answer today
> shouldn't prevent us from adopting the right model for values and
> references.

I think that depends on what you mean by this.  If you mean providing a default 
equality of reference identity for reference types I disagree.  I think that 
should wait until the language reaches a place where there is no good reason to 
write value semantic reference types.  And I believe the boilerplate currently 
required to wrap them in a struct is sufficiently burdensome that this is not 
the case yet.


> 
>> For something like the standard library these concerns are far
>> outweighed by the benefit we all gain by having our collections be
>> value types. However, in application code the benefit may not be worth
>> the cost thus it may be reasonable to prefer immutable objects.
>> 
>> I think there is a viable path for enhancing the language such that there is
>> little or not reason to implement a value semantic type as a reference type. 
>> If
>> we were able to declare value types as "indirect" and / or have a compiler
>> supported Box (probably with s

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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 3:53 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  wrote:
> 
>> Sent from my iPad
>> 
>> On May 7, 2016, at 2:21 AM, Andrew Trick via swift-evolution
>>  wrote:
>> 
>>On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>I don’t mean to imply that it is the *only* valuable
>>property. However, it I (and many others) do believe it is an
>>extremely valuable
>>property in many cases. Do you disagree?
>> 
>>I think I do. What is valuable about such a protocol? What generic
>>algorithms could you write that work on models of PureValue but don't
>>work just as well on Array?
>> 
>>class Storage {
>>var element: Int = 0
>>}
>> 
>>struct Value {
>>var storage: Storage
>>}
>> 
>>func amIPure(v: Value) -> Int {
>>v.storage.element = 3
>>return v.storage.element
>>}
>> 
>>I (the optimizer) want to know if 'amIPure' is a pure function. The
>>developer needs to tell me where the boundaries of the value lie. Does
>>'storage' lie inside the Value, or outside? If it is inside, then Value 
>> is a
>>'PureValue' and 'amIPure' is a pure function. To enforce that, the 
>> developer
>>will need to implement CoW, or we need add some language features.
>> 
>> Thank you for this clear exposition of how PureValue relates to pure 
>> functions.
>> This is the exact intuition I have about it but you have stated it much more
>> clearly.
>> 
>> Language features to help automate CoW would be great. It would eliminate
>> boilerplate, but more importantly it would likely provide more information to
>> the compiler.
> 
> Whoa; Andy never suggested this would help automate CoW.  Are you
> suggesting that?  How would it work?

Quoting Andy:

"I (the optimizer) want to know if 'amIPure' is a pure function. The developer 
needs to tell me where the boundaries of the value lie. Does 'storage' lie 
inside the Value, or outside? If it is inside, then Value is a 'PureValue' and 
'amIPure' is a pure function. To enforce that, the developer will need to 
implement CoW, or we need add some language features."

I was referring to new language features that eliminate the need for the 
developer to implement CoW manually while preserving the same semantics.  

I don’t know about the general case, but in simple cases I can imagine a 
feature such as “indirect struct” or Box which would contain a 
reference to a struct on the heap.  Any time a mutating operation was performed 
on a non-uniquely referenced struct it would be copied first and the internal 
reference updated to point to the new copy on the heap.  This is the kind of 
thing I had in mind when I said “automating CoW”.


> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 3:48 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  > wrote:
> 
>> Sent from my iPad
>> 
>>> On May 6, 2016, at 8:54 PM, Dave Abrahams  wrote:
>>> 
>>> 
 on Fri May 06 2016, Matthew Johnson  wrote:
 
   On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
wrote:
 
   on Thu May 05 2016, Matthew Johnson  wrote:
 
   On May 5, 2016, at 10:02 PM, Dave Abrahams
wrote:
 
   on Thu May 05 2016, Matthew Johnson  
 wrote:
 
   On May 5, 2016, at 4:59 PM, Dave Abrahams
wrote:
 
   on Wed May 04 2016, Matthew Johnson  
 wrote:
 
   On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
wrote:
 
   on Wed May 04 2016, Matthew Johnson
wrote:
 
   On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
wrote:
 
   on Wed May 04 2016, Adrian Zubarev
   
   wrote:
 
   Not sure what to think about the enum cases inside a
   protocol (if AnyEnum would
   even exist), it could be a nice addition to the language, but
   this is an own
   proposal I guess.
 
   We should start by adding AnyValue protocol to which all value
   types
   conforms.
 
   Having a way to constrain conformance to things with value semantics
   is
   something I've long wanted. *However*, the approach described is too
   simplistic. It's possible to build classes whose instances have
   value
   semantics (just make them immutable) and it's possible to build
   structs
   whose instances have reference semantics (just put the struct's
   storage
   in a mutable class instance that it holds as a property, and don't
   do
   copy-on-write). 
 
   In order for something like AnyValue to have meaning, we need to
   impose
   greater order. After thinking through many approaches over the
   years, I
   have arrived at the (admittedly rather drastic) opinion that the
   language should effectively outlaw the creation of structs and enums
   that don't have value semantics. (I have no problem with the idea
   that
   immutable classes that want to act as values should be wrapped in a
   struct). The language could then do lots of things much more
   intelligently, such as correctly generating implementations of
   equality.
 
   That is a drastic solution indeed! How would this impact things like
   Array? While Array itself has value semantics, the aggregate
   obviously does not as it contains references which usually be mutated
   underneath us. 
 
   Value semantics and mutation can only be measured with respect to
   equality. The definition of == for all class types would be 
 equivalent
   to ===. Problem solved.
 
   Similar considerations apply to simpler wrapper structs such as Weak.
 
   Same answer.
 
   Hmm. If those qualify as “value semantic” then what kind of structs 
 and
   enums
   would not? A struct wrapping a mutable reference type certainly 
 doesn’t
   “feel”
   value semantic to me and certainly doesn’t have the guarantees 
 usually
   associated with value semantics (won’t mutate behind your back, 
 thread
   safe,
   etc).
 
   Sure it does.
 
   public struct Wrap : Equatable {
   init(_ x: T) { self.x = x }
   private x: T
   }
 
   func == (lhs: Wrap, rhs: Wrap) -> Bool {
   return lhs.x === rhs.x
   }
 
   I defy you to find any scenario where Wrap doesn't have value
   semantics, whether T is mutable or not.
 
   Alternately, you can look at the Array implementation. Array is a
   struct wrapping a mutable class. It has value semantics by virtue of
   CoW.
 
   This goes back to where you draw the line as to the “boundary of the
   value”.
   Wrap and Array are “value semantic” in a shallow sense and are 
 capable
   of deep
   value semantics when T is deeply value semantic. 
 
   No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
 from
   not understanding the boundaries of your value. Or, put more
   solicitously: sure, you can look at the world that way, but it just
   makes everything prohibitively complicated, so why would you want to?
 
   In my world, there's no such thing as a “deep copy” or a “shallow 
 copy;”
   there's 

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

2016-05-07 Thread Matthew Johnson via swift-evolution

> On May 7, 2016, at 3:03 PM, Dave Abrahams  wrote:
> 
> 
> on Sat May 07 2016, Matthew Johnson  wrote:
> 
>> This depends on the type. For types representing resources, etc it works just
>> fine. But for models it does not work unless the model subgraph is entirely
>> immutable and instances are unique. 
>> I agree that it isn't a good idea to provide a default that will
>> certainly be wrong in many cases.
> 
> Please show an example of a mutable model where such an equality would
> be wrong.  

This is somewhat orthogonal to the main points I have been making in this 
thread.  I have been focused on discussion about reference types that have 
value semantics and the distinction between value semantics and pure values.  
In any case, here you go:

let a: NSMutableArray = [1, 2, 3]
let other: NSMutableArray = [1, 2, 3]
let same = a === other // false
let equal = a == other // true

Reference equality does not match the behavior of many existing mutable model 
types.  You seem to be making a case that in Swift it should.  But that is a 
separate discussion from the one I am trying to engage in because mutable 
reference types *do not* have value semantics.  

> 
>>I assume what is meant by "PureValue", is any object A, whose own 
>> references
>>form a subgraph, within which a change to any of the values would 
>> constitute
>>a change in the value of A (thus impermissible if A is immutable). Thus
>>structs would quality as “PureValues”.
>> 
>> As you noted in a followup, not all structs qualify. Structs that whose 
>> members
>> all qualify will qualify. References to a subgraph that doesn't allow for any
>> observable mutation (i.e. deeply immutable reference types) also qualify.
>> 
>> This means the following qualify:
>> 
>> * primitive structs and enums
>> * observable immutable object subgraphs
>> * any type composed from the previous
>> 
>> It follows that generic types often conditionally qualify depending on their
>> type arguments.
>> 
>>I also assume that enforcing immutability on an object graph, via CoW or
>>otherwise, would be unfeasible. You could enforce it on all values
>>accessible by traversing a single reference for reference types, however.
>> 
>>This is why I don’t really buy the argument that there is no such this as
>>deep vs shallow copy. Deep copy means copying the whole “PureValue” or
>>subgraph, shallow copy means traversing a single reference and copying all
>>accessible values.
>> 
>>I don’t mean to imply that it is the *only* valuable
>>property. However, it I (and many others) do believe it is an
>>extremely
>>valuable
>>property in many cases. Do you disagree?
>> 
>>I think I do. What is valuable about such a protocol? What generic
>>algorithms could you write that work on models of PureValue but
>>don't
>>work just as well on Array?
>> 
>>Array provides the semantics I have in mind just fine so 
>> there
>>wouldn’t be
>>any. Array is a completely different story. With
>>Array you cannot rely on a guarantee the objects
>>contained
>>in the array will not be mutated by code elsewhere that also 
>> happens
>>to have a reference to the same objects.
>> 
>>Okay then, what algorithms can you write that operate on PureValue 
>> that
>>don't work equally well on Array?
> 
> You haven't answered this question.  How would you use this protocol?

I answered elsewhere but I’ll repeat that one use that immediately comes to 
mind is to constrain values received in the initializer of a (view) controller 
to ensure that the observable state will not change over time.  This is not an 
algorithmic use but is still perfectly valid IMO.

If I read Andrew’s post correctly it sounds like it may also be of use to the 
optimizer in some cases.

> 
>>let t = MyClass()
>>foo.acceptWrapped(Wrap(t))
>>t.mutate()
>> 
>>In this example, foo had better not depend on the wrapped instance
>>not
>>getting
>>mutated.
>> 
>>foo has no way to get at the wrapped instance, so it can't depend 
>> on
>>anything about it.
>> 
>>Ok, but this is a toy example. What is the purpose of Wrap? Maybe
>>foo
>>passes the
>>wrapped instance back to code that *does* have visibility to the
>>instance. My
>>point was that shared mutable state is still possible here. 
>> 
>>And my point is that Wrap encapsulates a T (almost—I should 
>> have
>>let
>>it construct the T in its init rather than accepting a T 
>> parameter)
>>and
>>the fact that it's *possible* to code something with the structure
>>of
>>Wrap so that it h

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

2016-05-07 Thread Andrew Trick via swift-evolution

> On May 7, 2016, at 2:04 PM, Dave Abrahams  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 is not a “pure” value (the buffer contained in an
> Array 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. Does Array have value semantics then only if 
T also has value semantics?

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. That 
fact is what allows the compiler to ignore mutation of the buffer.

It's perfectly clear that Array is a PureValue iff T is a PureValue. 
PureValue is nothing more than transitive value semantics.

At any rate, we could add a PureValue magic protocol, and it would have 
well-defined meaning. I'm not sure that it is worthwhile or even a good way to 
approach the problem. But we don't need to argue about the definition.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Tyler Fleming Cloutier via swift-evolution

> On May 7, 2016, at 12:52 PM, Dave Abrahams  wrote:
> 
> 
> on Fri May 06 2016, Tyler Fleming Cloutier  wrote:
> 
>>On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Fri May 06 2016, Matthew Johnson  wrote:
>> 
>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>Swift’s collections also accomplish this through copying, but only 
>> when
>>the
>>elements they contain also have the same property. 
>> 
>>Only if you think mutable class instances are part of the value of the
>>array that stores references to those class instances. As I said
>>earlier, you can *take* that point of view, but why would you want to?
>>Today, we have left that question wide open, which makes the whole
>>notion of what is a logical value very indistinct. I am proposing to
>>close it.
>> 
>>On the other hand, it is immediately obvious that non-local mutation
>>is quite possibly in the elements of a Swift Array unless
>>they are all uniquely referenced.
>> 
>>If you interpret the elements of the array as being *references* to
>>objects, there is no possibility of non-local mutation. If you
>>interpret the elements as being objects *themselves*, then you've got
>>problems.
>> 
>> This does not make sense, because you’ve got problems either way. You are
>> arguing, essentially, that everything is a value type because
>> references/pointers are a value. 
> 
> I am arguing that every type can be viewed as a value, allowing us to
> preserve a sense in which Array has value semantics irrespective of
> the details of T.
> 
>> If that were the case then the *only* valid way to compare the
>> equality of types would be to compare their values. Overriding the
>> equality operator would inherently violate the property of
>> immutability, i.e. two immutable objects can change their equality
>> even without mutation of their “values".
> 
> Not at all.  In my world, you can override equality such that it
> includes referenced storage when either:
> 
> 1. the referenced storage will not be mutated
> 2. or, the referenced storage will only mutated when uniquely-referenced.
> 
>> 
>> func ==(lhs, rhs) {
>> ...
>> }
>> 
>> class MyClass {
>> var a: Int
>> ...
>> 
>> } 
>> 
>> let x = MyClass(a: 5)
>> let y = MyClass(a: 5)
>> 
>> x == y // true
>> y.a = 6
>> x == y // false
> 
> I don't understand what point you're trying to make, here.  I see that x
> and y are immutable. Notwithstanding the fact that the language tries to
> hide the difference between a reference and the instance to which it
> refers from the user (the difference would be clearer if you had to
> write y->a = 6 as in C, but it's still there), that immutability doesn't
> extend beyond the variable binding.  The class instance to which y
> refers, as you've ably demonstrated, is mutable.
> 

The point I’m trying to make is that in the above code, I am able to violate 
rule 1 of your world insofar as I am including referenced storage in my 
definition of equality which can be mutated even though my reference is 
immutable.

>>Are you arguing that reference types should be equatable by default,
>>using
>>equality of the reference if the type does not provide a custom
>>definition of
>>equality?
>> 
>>Yes!!
>> 
>> Custom definitions of equality, inherently, decouple immutability from
>> equality,
> 
> Not a bit.  They certainly *can* do that, if we allow it, but I am
> proposing to ban that.  There are still useful custom definitions of
> equality as I have outlined above.

If you’re proposing to ban that, then I may have misunderstood your position. I 
think we are in agreement on that, however… (more below)

> 
>> as shown above. Swift makes it appear as though references and values
>> are on the same level in a way that C does not.
> 
> Yep.  It's an illusion that breaks down at the edges and can be really
> problematic if users fully embrace it.  You can't write a generic
> algorithm with well-defined semantics that does mutation-by-part on
> instances of T without constraining T to have value or reference semantics.
> 
> I am not advocating that we require “y->a” for class member access, but
> I *am* suggesting that we should accept the fact that reference and
> value semantics are fundamentally different and make design choices
> (including language rules) accordingly.
> 
>> let x = MyStruct()
>> let y = MyClass()
>> 
>> x.myFoo
>> y.myFoo
>> 
>> vs
>> 
>> my_struct *x = …
>> my_struct y = …
>> 
>> x.my_foo
>> y->my_foo
>> 
>> With C it is explicit that you are crossing a reference. Thus there is only
>> *one* type of equality in C, that the values *are equal*. 
> 
> Well, C doesn't even *have* struct equality;
> http://stackoverflow.com/a/141724
> 
>> This exactly the type of equality you are referring to, but this does
>> not carry over to Swift for precisely the reason that Swift pave

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Tyler Fleming Cloutier  wrote:

> That is a drastic solution indeed! How would this impact things like
> Array? While Array itself has value semantics, the aggregate
> obviously does not as it contains references which usually be mutated
> underneath us. 
>
> Value semantics and mutation can only be measured with respect to
> equality. The definition of == for all class types would be equivalent
> to ===. Problem solved.
>
> Hmm, I get the feeling that I was arguing your own point back at you. Sorry,
> Dave, I’m a little slow. :)
>
> Still, how would you generate an equality operator for a data structure that
> requires wrapper classes currently, like a LinkedList?

I don't think I understand the question.  Maybe you should show me the
specific LinkedList you're interested in.  When you say “generate,” do
you mean automatically?

FWIWs:

1. I don't intend to make every == operator automatically-generated

2. A LinkedList can be defined using enums and no classes

3. Though it can be done, I am of the opinion that linked lists usually
   make poor value types.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Tyler Fleming Cloutier  wrote:

> No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
> not understanding the boundaries of your value. Or, put more
> solicitously: sure, you can look at the world that way, but it just
> makes everything prohibitively complicated, so why would you want to?
>
> In my world, there's no such thing as a “deep copy” or a “shallow copy;”
> there's just “copy,” which logically creates an independent version of
> everything up to the boundaries of the value. Likewise, there's no
> “deep value semantics” or “shallow value semantics.” Equality defines
> value semantics, and the boundaries of an Array value always includes
> the values of its elements. The *only* problem here is that we have no
> way to do equality comparison on some arrays because some types aren't
> Equatable. IMO the costs of not having everything be equatable, in
> complexity-of-programming-model terms, are too high.
>
> My point with this is, in case I was a bit rambling, if you’re going to draw
> boundaries around a value, for the purpose of copying or immutability, then
> equality should always match with those boundaries. 

Quite.

> As you say, “Equality defines value semantics, and the boundaries of
> an Array value always includes the values of its elements.”
>
> Under this reasoning, custom equality violates these boundaries. 

No, it defines those boundaries.

> And without custom equality, equality checks on reference types are
> essentially useless. 

No, comparing reference identity is completely useful.  That's why “===”
exists.  We just spelled it wrong :-)



-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

> I've been thinking about this further and can now state my position more 
> clearly
> and concisely.
>
> 1. If we're going to have reference types with value semantics the boundary of
> the value must extend through the reference to the value of the object. Two
> instances may have the same logical value so reference equality is not good
> enough.

My (radical) position has been that we should decree that if you really
want this thing to have value semantics, it should be a struct.  That
is, wrap your reference type in a struct and provide an == that looks at
what's in the instance.  This radically simplifies the model because we
can then assume that value types have value semantics and reference
types only have value semantics if you view their identitity as their
value.

> 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 is not a “pure” value (the buffer contained in an
Array 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.

> Purity must include the entire aggregate. Array has value
> semantics but it is not a pure value.

In what sense does it have value semantics?  Unless we can define
equality for Array it's hard to make any claim about its value
semantics.

> The primary reasons I can think of for creating reference types with value
> semantics are avoiding copying everything all the time or using inheritance. 
> (I
> could also list pre-existing types here but am not as concerned with those)
>
> One could argue that you can avoid copying by writing a struct with a handle 
> and
> one can simulate inheritance by embedding and forwarding. The problem is that
> this involves a lot of boilerplate and makes your code more complex. 

The “forwarding boilerplate problem” is something we need to solve in
the language regardless.  The fact that we don't have an answer today
shouldn't prevent us from adopting the right model for values and
references.

> For something like the standard library these concerns are far
> outweighed by the benefit we all gain by having our collections be
> value types. However, in application code the benefit may not be worth
> the cost thus it may be reasonable to prefer immutable objects.
>
> I think there is a viable path for enhancing the language such that there is
> little or not reason to implement a value semantic type as a reference type. 
> If
> we were able to declare value types as "indirect" and / or have a compiler
> supported Box (probably with syntactic sugar) that automatically forwarded
> calls, performed CoW, etc this would allow us much more control over copying
> without requiring boilerplate. We could also add something along the lines of
> Go's embedding (or a more general forwarding mechanism which is my preference)
> which would likely address many of the reasons for using inheritance in a 
> value
> semantic reference type.
>
> If we do go down that path I think the case that value semantic types should 
> be
> implemented as value types, thus reference equality should be the default
> equality for reference types gets much stronger. In that hypothetical future
> Swift we might even be able to go so far as saying that reference types with
> value semantics are an anti-pattern and "outlaw" them. This would allow us to
> simply say "reference types have reference semantics". 
>
> We might also be able to get to a place where we can "outlaw" value types that
> do not have value semantics. I haven't thought deeply about that so I'm not
> certain of the implications, particularly with regards to C interop. IIRC 
> Dave A
> indicated he would like to see this happen. If this is possible, we may
> eventually have a language where "value types have value semantics", "some 
> value
> types are pure values", and "reference types have reference semantics and are
> never pure values". If it is achievable it would be a significant step forward
> in simplicity and clarity. 

So far, I still don't believe that introducing a “pure values” distinction is
adding simplicity and clarity.  To me it looks like a needless wrinkle.

> Matthew
>
> Sent from my iPad
>
> On May 7, 2016, at 11:17 AM, Matthew Johnson  wrote:
>
> Sent from my iPad
>
> On May 7, 2016, at 2:21 AM, Andrew Trick via swift-evolution
>  wrote:
>
> On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> I don’t mean to imply that it is the *only* valuable
> property. However, it I (and many others) do believe it is an
> extremely valuable
> property in many cases. Do you disagree?
>
> I think I do. What is valuable about such a protocol? What generic
> algorithms could yo

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

> Sent from my iPad
>
> On May 7, 2016, at 2:21 AM, Andrew Trick via swift-evolution
>  wrote:
>
> On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> I don’t mean to imply that it is the *only* valuable
> property. However, it I (and many others) do believe it is an
> extremely valuable
> property in many cases. Do you disagree?
>
> I think I do. What is valuable about such a protocol? What generic
> algorithms could you write that work on models of PureValue but don't
> work just as well on Array?
>
> class Storage {
> var element: Int = 0
> }
>
> struct Value {
> var storage: Storage
> }
>
> func amIPure(v: Value) -> Int {
> v.storage.element = 3
> return v.storage.element
> }
>
> I (the optimizer) want to know if 'amIPure' is a pure function. The
> developer needs to tell me where the boundaries of the value lie. Does
> 'storage' lie inside the Value, or outside? If it is inside, then Value 
> is a
> 'PureValue' and 'amIPure' is a pure function. To enforce that, the 
> developer
> will need to implement CoW, or we need add some language features.
>
> Thank you for this clear exposition of how PureValue relates to pure 
> functions.
> This is the exact intuition I have about it but you have stated it much more
> clearly.
>
> Language features to help automate CoW would be great. It would eliminate
> boilerplate, but more importantly it would likely provide more information to
> the compiler.

Whoa; Andy never suggested this would help automate CoW.  Are you
suggesting that?  How would it work?

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Andrew Trick  wrote:

> On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> I don’t mean to imply that it is the *only* valuable
> property. However, it I (and many others) do believe it is an 
> extremely
> valuable
> property in many cases. Do you disagree?
>
> I think I do. What is valuable about such a protocol? What generic
> algorithms could you write that work on models of PureValue but don't
> work just as well on Array?
>
> class Storage {
> var element: Int = 0
> }
>
> struct Value {
> var storage: Storage
> }
>
> func amIPure(v: Value) -> Int {
> v.storage.element = 3
> return v.storage.element
> }
>
> I (the optimizer) want to know if 'amIPure' is a pure function. The developer
> needs to tell me where the boundaries of the value lie. Does 'storage' lie
> inside the Value, or outside? If it is inside, then Value is a 'PureValue' and
> 'amIPure' is a pure function. To enforce that, the developer will need to
> implement CoW, or we need add some language features.
>
> If I know about every operation inside 'amIPure', and know where the value's
> boundary is, then I don't really need to know that 'Value' is a 'PureValue'. 
> For
> example, I know that this function is pure without caring about 'PureValue'.
>
> func IAmPure(v: Value, s: Storage) -> Int {
> var t = v
> t.storage = s
> return t.storage.element
> }

How do you know this?  t.storage can be a computed property.  I think
you're assuming a lot of information is being communicated to me and to
the compiler from the types in the signature (e.g. can Value be a
reference type?)

> However, I might only have summary information. I might know that the function
> only writes to memory reachable from Value. In that case, it would be nice to
> have summary information about the storage type. 'PureValue' is another way of
> saying that it does not contain references to objects outside the value's
> boundary (I would add that it cannot have a user-defined deinit). The only 
> thing
> vague about that is that we don't have a general way for the developer to 
> define
> the value's boundary. It certainly should be consistent with '==', but
> implementing '==' doesn't tell the optimizer anything.
>
> Anyway, these are only optimizer concerns, and programming model should take
> precedence in these discussion. 

Indeed, I am arguing from the point of view of the programming model.  I
am very wary of introducing protocols that are only there for the use of
the optimizer.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

> Sent from my iPad
>
>> On May 6, 2016, at 8:54 PM, Dave Abrahams  wrote:
>> 
>> 
>>> on Fri May 06 2016, Matthew Johnson  wrote:
>>> 
>>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson  wrote:
>>> 
>>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson  
>>> wrote:
>>> 
>>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson  
>>> wrote:
>>> 
>>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson
>>> wrote:
>>> 
>>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Wed May 04 2016, Adrian Zubarev
>>>
>>>wrote:
>>> 
>>>Not sure what to think about the enum cases inside a
>>>protocol (if AnyEnum would
>>>even exist), it could be a nice addition to the language, but
>>>this is an own
>>>proposal I guess.
>>> 
>>>We should start by adding AnyValue protocol to which all value
>>>types
>>>conforms.
>>> 
>>>Having a way to constrain conformance to things with value semantics
>>>is
>>>something I've long wanted. *However*, the approach described is too
>>>simplistic. It's possible to build classes whose instances have
>>>value
>>>semantics (just make them immutable) and it's possible to build
>>>structs
>>>whose instances have reference semantics (just put the struct's
>>>storage
>>>in a mutable class instance that it holds as a property, and don't
>>>do
>>>copy-on-write). 
>>> 
>>>In order for something like AnyValue to have meaning, we need to
>>>impose
>>>greater order. After thinking through many approaches over the
>>>years, I
>>>have arrived at the (admittedly rather drastic) opinion that the
>>>language should effectively outlaw the creation of structs and enums
>>>that don't have value semantics. (I have no problem with the idea
>>>that
>>>immutable classes that want to act as values should be wrapped in a
>>>struct). The language could then do lots of things much more
>>>intelligently, such as correctly generating implementations of
>>>equality.
>>> 
>>>That is a drastic solution indeed! How would this impact things like
>>>Array? While Array itself has value semantics, the aggregate
>>>obviously does not as it contains references which usually be mutated
>>>underneath us. 
>>> 
>>>Value semantics and mutation can only be measured with respect to
>>>equality. The definition of == for all class types would be 
>>> equivalent
>>>to ===. Problem solved.
>>> 
>>>Similar considerations apply to simpler wrapper structs such as Weak.
>>> 
>>>Same answer.
>>> 
>>>Hmm. If those qualify as “value semantic” then what kind of structs 
>>> and
>>>enums
>>>would not? A struct wrapping a mutable reference type certainly 
>>> doesn’t
>>>“feel”
>>>value semantic to me and certainly doesn’t have the guarantees 
>>> usually
>>>associated with value semantics (won’t mutate behind your back, 
>>> thread
>>>safe,
>>>etc).
>>> 
>>>Sure it does.
>>> 
>>>public struct Wrap : Equatable {
>>>init(_ x: T) { self.x = x }
>>>private x: T
>>>}
>>> 
>>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>>return lhs.x === rhs.x
>>>}
>>> 
>>>I defy you to find any scenario where Wrap doesn't have value
>>>semantics, whether T is mutable or not.
>>> 
>>>Alternately, you can look at the Array implementation. Array is a
>>>struct wrapping a mutable class. It has value semantics by virtue of
>>>CoW.
>>> 
>>>This goes back to where you draw the line as to the “boundary of the
>>>value”.
>>>Wrap and Array are “value semantic” in a shallow sense and are 
>>> capable
>>>of deep
>>>value semantics when T is deeply value semantic. 
>>> 
>>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
>>> from
>>>not understanding the boundaries of your value. Or, put more
>>>solicitously: sure, you can look at the world that way, but it just
>>>makes everything prohibitively complicated, so why would you want to?
>>> 
>>>In my world, there's no such thing as a “deep copy” or a “shallow 
>>> copy;”
>>>there's just “copy,” which logically creates an independent version 
>>> of
>>>everything up to the boundaries of the value. Likewise, there's 

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Sat May 07 2016, Matthew Johnson  wrote:

> This depends on the type. For types representing resources, etc it works just
> fine. But for models it does not work unless the model subgraph is entirely
> immutable and instances are unique. 
> I agree that it isn't a good idea to provide a default that will
> certainly be wrong in many cases.

Please show an example of a mutable model where such an equality would
be wrong.  

> I assume what is meant by "PureValue", is any object A, whose own 
> references
> form a subgraph, within which a change to any of the values would 
> constitute
> a change in the value of A (thus impermissible if A is immutable). Thus
> structs would quality as “PureValues”.
>
> As you noted in a followup, not all structs qualify. Structs that whose 
> members
> all qualify will qualify. References to a subgraph that doesn't allow for any
> observable mutation (i.e. deeply immutable reference types) also qualify.
>
> This means the following qualify:
>
> * primitive structs and enums
> * observable immutable object subgraphs
> * any type composed from the previous
>
> It follows that generic types often conditionally qualify depending on their
> type arguments.
>
> I also assume that enforcing immutability on an object graph, via CoW or
> otherwise, would be unfeasible. You could enforce it on all values
> accessible by traversing a single reference for reference types, however.
>
> This is why I don’t really buy the argument that there is no such this as
> deep vs shallow copy. Deep copy means copying the whole “PureValue” or
> subgraph, shallow copy means traversing a single reference and copying all
> accessible values.
>
> I don’t mean to imply that it is the *only* valuable
> property. However, it I (and many others) do believe it is an
> extremely
> valuable
> property in many cases. Do you disagree?
>
> I think I do. What is valuable about such a protocol? What generic
> algorithms could you write that work on models of PureValue but
> don't
> work just as well on Array?
>
> Array provides the semantics I have in mind just fine so 
> there
> wouldn’t be
> any. Array is a completely different story. With
> Array you cannot rely on a guarantee the objects
> contained
> in the array will not be mutated by code elsewhere that also 
> happens
> to have a reference to the same objects.
>
> Okay then, what algorithms can you write that operate on PureValue 
> that
> don't work equally well on Array?

You haven't answered this question.  How would you use this protocol?

> let t = MyClass()
> foo.acceptWrapped(Wrap(t))
> t.mutate()
>
> In this example, foo had better not depend on the wrapped instance
> not
> getting
> mutated.
>
> foo has no way to get at the wrapped instance, so it can't depend 
> on
> anything about it.
>
> Ok, but this is a toy example. What is the purpose of Wrap? Maybe
> foo
> passes the
> wrapped instance back to code that *does* have visibility to the
> instance. My
> point was that shared mutable state is still possible here. 
>
> And my point is that Wrap encapsulates a T (almost—I should 
> have
> let
> it construct the T in its init rather than accepting a T 
> parameter)
> and
> the fact that it's *possible* to code something with the structure
> of
> Wrap so that it has shared mutable state is irrelevant.
>
> The point I am trying to make is that the semantic properties of
> Wrap depend
> on the semantic properties of T (whether or not non-local mutation
> may be
> observed in this case). 
>
> No they do not; Wrap was specifically designed *not* to depend on 
> the
> semantic properties of T. This was in answer to what you said:
>
> A struct wrapping a mutable reference type certainly doesn’t
> “feel” value semantic to me and certainly doesn’t have the
> guarantees usually associated with value semantics (won’t
> mutate behind your back, thread safe, etc).
>
> I have been trying to get you to nail down what you mean by PureValue,
> and I was trying to illustrate that merely being “a struct wrapping a
> mutable reference type” is not enough to disqualify anything from 
> being
> in the category you're trying to describe. What are the properties of
> types in that category, and what generic code would depend on those
> properties?

Again, the key questions are above, ask

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

2016-05-07 Thread Dave Abrahams via swift-evolution

on Fri May 06 2016, Tyler Fleming Cloutier  wrote:

> On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Fri May 06 2016, Matthew Johnson  wrote:
>
> On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> Swift’s collections also accomplish this through copying, but only 
> when
> the
> elements they contain also have the same property. 
>
> Only if you think mutable class instances are part of the value of the
> array that stores references to those class instances. As I said
> earlier, you can *take* that point of view, but why would you want to?
> Today, we have left that question wide open, which makes the whole
> notion of what is a logical value very indistinct. I am proposing to
> close it.
>
> On the other hand, it is immediately obvious that non-local mutation
> is quite possibly in the elements of a Swift Array unless
> they are all uniquely referenced.
>
> If you interpret the elements of the array as being *references* to
> objects, there is no possibility of non-local mutation. If you
> interpret the elements as being objects *themselves*, then you've got
> problems.
>
> This does not make sense, because you’ve got problems either way. You are
> arguing, essentially, that everything is a value type because
> references/pointers are a value. 

I am arguing that every type can be viewed as a value, allowing us to
preserve a sense in which Array has value semantics irrespective of
the details of T.

> If that were the case then the *only* valid way to compare the
> equality of types would be to compare their values. Overriding the
> equality operator would inherently violate the property of
> immutability, i.e. two immutable objects can change their equality
> even without mutation of their “values".

Not at all.  In my world, you can override equality such that it
includes referenced storage when either:

1. the referenced storage will not be mutated
2. or, the referenced storage will only mutated when uniquely-referenced.

>
> func ==(lhs, rhs) {
> ...
> }
>
> class MyClass {
> var a: Int
> ...
>
> } 
>
> let x = MyClass(a: 5)
> let y = MyClass(a: 5)
>
> x == y // true
> y.a = 6
> x == y // false

I don't understand what point you're trying to make, here.  I see that x
and y are immutable. Notwithstanding the fact that the language tries to
hide the difference between a reference and the instance to which it
refers from the user (the difference would be clearer if you had to
write y->a = 6 as in C, but it's still there), that immutability doesn't
extend beyond the variable binding.  The class instance to which y
refers, as you've ably demonstrated, is mutable.

> Are you arguing that reference types should be equatable by default,
> using
> equality of the reference if the type does not provide a custom
> definition of
> equality?
>
> Yes!!
>
> Custom definitions of equality, inherently, decouple immutability from
> equality,

Not a bit.  They certainly *can* do that, if we allow it, but I am
proposing to ban that.  There are still useful custom definitions of
equality as I have outlined above.

> as shown above. Swift makes it appear as though references and values
> are on the same level in a way that C does not.

Yep.  It's an illusion that breaks down at the edges and can be really
problematic if users fully embrace it.  You can't write a generic
algorithm with well-defined semantics that does mutation-by-part on
instances of T without constraining T to have value or reference semantics.

I am not advocating that we require “y->a” for class member access, but
I *am* suggesting that we should accept the fact that reference and
value semantics are fundamentally different and make design choices
(including language rules) accordingly.

> let x = MyStruct()
> let y = MyClass()
>
> x.myFoo
> y.myFoo
>
> vs
>
> my_struct *x = …
> my_struct y = …
>
> x.my_foo
> y->my_foo
>
> With C it is explicit that you are crossing a reference. Thus there is only
> *one* type of equality in C, that the values *are equal*. 

Well, C doesn't even *have* struct equality;
http://stackoverflow.com/a/141724

> This exactly the type of equality you are referring to, but this does
> not carry over to Swift for precisely the reason that Swift paves over
> the difference between value and reference types, and then allows you
> to redefine equality.
>
> Therefore, in essentially no circumstances does it make sense to
> compare a type by its reference if it has any associated data in
> Swift. 

Disagreed.  Instances whose *identity* is significant, i.e. basically
everything that actually ought to be a class, can be very usefully
compared by their references.  For example, if equality and hashing were
defined for UIViews, based on their references, you could use a
Set to keep track of which views had user interaction during a
given time 

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

2016-05-07 Thread Matthew Johnson via swift-evolution
I've been thinking about this further and can now state my position more 
clearly and concisely.

1. If we're going to have reference types with value semantics the boundary of 
the value must extend through the reference to the value of the object.  Two 
instances may have the same logical value so reference equality is not good 
enough.

2. Value types are not "pure" values if any part of the aggregate contains a 
reference whose type does not have value semantics.  Purity must include the 
entire aggregate.  Array has value semantics but it is not a pure value.

The primary reasons I can think of for creating reference types with value 
semantics are avoiding copying everything all the time or using inheritance.  
(I could also list pre-existing types here but am not as concerned with those)

One could argue that you can avoid copying by writing a struct with a handle 
and one can simulate inheritance by embedding and forwarding.  The problem is 
that this involves a lot of boilerplate and makes your code more complex.  For 
something like the standard library these concerns are far outweighed by the 
benefit we all gain by having our collections be value types.  However, in 
application code the benefit may not be worth the cost thus it may be 
reasonable to prefer immutable objects.

I think there is a viable path for enhancing the language such that there is 
little or not reason to implement a value semantic type as a reference type.  
If we were able to declare value types as "indirect" and / or have a compiler 
supported Box (probably with syntactic sugar) that automatically forwarded 
calls, performed CoW, etc this would allow us much more control over copying 
without requiring boilerplate.  We could also add something along the lines of 
Go's embedding (or a more general forwarding mechanism which is my preference) 
which would likely address many of the reasons for using inheritance in a value 
semantic reference type.

If we do go down that path I think the case that value semantic types should be 
implemented as value types, thus reference equality should be the default 
equality for reference types gets much stronger.  In that hypothetical future 
Swift we might even be able to go so far as saying that reference types with 
value semantics are an anti-pattern and "outlaw" them.  This would allow us to 
simply say "reference types have reference semantics".  

We might also be able to get to a place where we can "outlaw" value types that 
do not have value semantics.  I haven't thought deeply about that so I'm not 
certain of the implications, particularly with regards to C interop.  IIRC Dave 
A indicated he would like to see this happen.  If this is possible, we may 
eventually have a language where "value types have value semantics", "some 
value types are pure values", and "reference types have reference semantics and 
are never pure values".  If it is achievable it would be a significant step 
forward in simplicity and clarity.  

Matthew

Sent from my iPad

> On May 7, 2016, at 11:17 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On May 7, 2016, at 2:21 AM, Andrew Trick via swift-evolution 
>>  wrote:
>> 
>> 
 On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution 
  wrote:
 
 I don’t mean to imply that it is the *only* valuable
 property. However, it I (and many others) do believe it is an extremely 
 valuable
 property in many cases. Do you disagree?
>>> 
>>> I think I do.  What is valuable about such a protocol?  What generic
>>> algorithms could you write that work on models of PureValue but don't
>>> work just as well on Array?
>> 
>> class Storage {
>>   var element: Int = 0
>> }
>> 
>> struct Value {
>>   var storage: Storage
>> }
>> 
>> func amIPure(v: Value) -> Int {
>>   v.storage.element = 3
>>   return v.storage.element
>> }
>> 
>> I (the optimizer) want to know if 'amIPure' is a pure function. The 
>> developer needs to tell me where the boundaries of the value lie. Does 
>> 'storage' lie inside the Value, or outside? If it is inside, then Value is a 
>> 'PureValue' and 'amIPure' is a pure function. To enforce that, the developer 
>> will need to implement CoW, or we need add some language features.
> 
> Thank you for this clear exposition of how PureValue relates to pure 
> functions.  This is the exact intuition I have about it but you have stated 
> it much more clearly.
> 
> Language features to help automate CoW would be great.  It would eliminate 
> boilerplate, but more importantly it would likely provide more information to 
> the compiler.
> 
>> 
>> If I know about every operation inside 'amIPure', and know where the value's 
>> boundary is, then I don't really need to know that 'Value' is a 'PureValue'. 
>> For example, I know that this function is pure without caring about 
>> 'PureValue'.
>> 
>> func IAmPure(v: Value, s: Storage) -> Int {
>>   var t = v
>>   t.storage = s
>>   return t.storage.element
>> }
>> 

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

2016-05-07 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 7, 2016, at 2:21 AM, Andrew Trick via swift-evolution 
>  wrote:
> 
> 
>>> On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> I don’t mean to imply that it is the *only* valuable
>>> property. However, it I (and many others) do believe it is an extremely 
>>> valuable
>>> property in many cases. Do you disagree?
>> 
>> I think I do.  What is valuable about such a protocol?  What generic
>> algorithms could you write that work on models of PureValue but don't
>> work just as well on Array?
> 
> class Storage {
>   var element: Int = 0
> }
> 
> struct Value {
>   var storage: Storage
> }
> 
> func amIPure(v: Value) -> Int {
>   v.storage.element = 3
>   return v.storage.element
> }
> 
> I (the optimizer) want to know if 'amIPure' is a pure function. The developer 
> needs to tell me where the boundaries of the value lie. Does 'storage' lie 
> inside the Value, or outside? If it is inside, then Value is a 'PureValue' 
> and 'amIPure' is a pure function. To enforce that, the developer will need to 
> implement CoW, or we need add some language features.

Thank you for this clear exposition of how PureValue relates to pure functions. 
 This is the exact intuition I have about it but you have stated it much more 
clearly.

Language features to help automate CoW would be great.  It would eliminate 
boilerplate, but more importantly it would likely provide more information to 
the compiler.

> 
> If I know about every operation inside 'amIPure', and know where the value's 
> boundary is, then I don't really need to know that 'Value' is a 'PureValue'. 
> For example, I know that this function is pure without caring about 
> 'PureValue'.
> 
> func IAmPure(v: Value, s: Storage) -> Int {
>   var t = v
>   t.storage = s
>   return t.storage.element
> }
> 
> However, I might only have summary information. I might know that the 
> function only writes to memory reachable from Value. In that case, it would 
> be nice to have summary information about the storage type. 'PureValue' is 
> another way of saying that it does not contain references to objects outside 
> the value's boundary (I would add that it cannot have a user-defined deinit). 
> The only thing vague about that is that we don't have a general way for the 
> developer to define the value's boundary. It certainly should be consistent 
> with '==', but implementing '==' doesn't tell the optimizer anything.

I think the ability to define the value's boundary would be wonderful.  If we 
added a way to do this it would be a requirement of PureValue.

> 
> Anyway, these are only optimizer concerns, and programming model should take 
> precedence in these discussion. But I thought that might help.
> 
> -Andy
> ___
> 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


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

2016-05-07 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 6, 2016, at 11:19 PM, Tyler Fleming Cloutier  
> wrote:
> 
> 
>> On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Fri May 06 2016, Matthew Johnson  wrote:
>> 
>>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson  wrote:
>>> 
>>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson  
>>> wrote:
>>> 
>>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson  
>>> wrote:
>>> 
>>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson
>>> wrote:
>>> 
>>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>>> wrote:
>>> 
>>>on Wed May 04 2016, Adrian Zubarev
>>>
>>>wrote:
>>> 
>>>Not sure what to think about the enum cases inside a
>>>protocol (if AnyEnum would
>>>even exist), it could be a nice addition to the language, but
>>>this is an own
>>>proposal I guess.
>>> 
>>>We should start by adding AnyValue protocol to which all value
>>>types
>>>conforms.
>>> 
>>>Having a way to constrain conformance to things with value semantics
>>>is
>>>something I've long wanted. *However*, the approach described is too
>>>simplistic. It's possible to build classes whose instances have
>>>value
>>>semantics (just make them immutable) and it's possible to build
>>>structs
>>>whose instances have reference semantics (just put the struct's
>>>storage
>>>in a mutable class instance that it holds as a property, and don't
>>>do
>>>copy-on-write). 
>>> 
>>>In order for something like AnyValue to have meaning, we need to
>>>impose
>>>greater order. After thinking through many approaches over the
>>>years, I
>>>have arrived at the (admittedly rather drastic) opinion that the
>>>language should effectively outlaw the creation of structs and enums
>>>that don't have value semantics. (I have no problem with the idea
>>>that
>>>immutable classes that want to act as values should be wrapped in a
>>>struct). The language could then do lots of things much more
>>>intelligently, such as correctly generating implementations of
>>>equality.
>>> 
>>>That is a drastic solution indeed! How would this impact things like
>>>Array? While Array itself has value semantics, the aggregate
>>>obviously does not as it contains references which usually be mutated
>>>underneath us. 
>>> 
>>>Value semantics and mutation can only be measured with respect to
>>>equality. The definition of == for all class types would be 
>>> equivalent
>>>to ===. Problem solved.
>>> 
>>>Similar considerations apply to simpler wrapper structs such as Weak.
>>> 
>>>Same answer.
>>> 
>>>Hmm. If those qualify as “value semantic” then what kind of structs 
>>> and
>>>enums
>>>would not? A struct wrapping a mutable reference type certainly 
>>> doesn’t
>>>“feel”
>>>value semantic to me and certainly doesn’t have the guarantees 
>>> usually
>>>associated with value semantics (won’t mutate behind your back, 
>>> thread
>>>safe,
>>>etc).
>>> 
>>>Sure it does.
>>> 
>>>public struct Wrap : Equatable {
>>>init(_ x: T) { self.x = x }
>>>private x: T
>>>}
>>> 
>>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>>return lhs.x === rhs.x
>>>}
>>> 
>>>I defy you to find any scenario where Wrap doesn't have value
>>>semantics, whether T is mutable or not.
>>> 
>>>Alternately, you can look at the Array implementation. Array is a
>>>struct wrapping a mutable class. It has value semantics by virtue of
>>>CoW.
>>> 
>>>This goes back to where you draw the line as to the “boundary of the
>>>value”.
>>>Wrap and Array are “value semantic” in a shallow sense and are 
>>> capable
>>>of deep
>>>value semantics when T is deeply value semantic. 
>>> 
>>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
>>> from
>>>not understanding the boundaries of your value. Or, put more
>>>solicitously: sure, you can look at the world that way, but it just
>>>makes everything prohibitively complicated, so why would you want to?
>>> 
>>>In my world, there's no such thing as a “deep copy” or a “shallow 
>>> copy;”
>>>there's just “copy,” which logically creates an independent version 
>>> of
>>>everything up to t

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

2016-05-07 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On May 6, 2016, at 8:54 PM, Dave Abrahams  wrote:
> 
> 
>> on Fri May 06 2016, Matthew Johnson  wrote:
>> 
>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Thu May 05 2016, Matthew Johnson  wrote:
>> 
>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>> wrote:
>> 
>>on Thu May 05 2016, Matthew Johnson  wrote:
>> 
>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson
>> wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev
>>
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value semantics
>>is
>>something I've long wanted. *However*, the approach described is too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>>Hmm. If those qualify as “value semantic” then what kind of structs 
>> and
>>enums
>>would not? A struct wrapping a mutable reference type certainly 
>> doesn’t
>>“feel”
>>value semantic to me and certainly doesn’t have the guarantees usually
>>associated with value semantics (won’t mutate behind your back, thread
>>safe,
>>etc).
>> 
>>Sure it does.
>> 
>>public struct Wrap : Equatable {
>>init(_ x: T) { self.x = x }
>>private x: T
>>}
>> 
>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>return lhs.x === rhs.x
>>}
>> 
>>I defy you to find any scenario where Wrap doesn't have value
>>semantics, whether T is mutable or not.
>> 
>>Alternately, you can look at the Array implementation. Array is a
>>struct wrapping a mutable class. It has value semantics by virtue of
>>CoW.
>> 
>>This goes back to where you draw the line as to the “boundary of the
>>value”.
>>Wrap and Array are “value semantic” in a shallow sense and are capable
>>of deep
>>value semantics when T is deeply value semantic. 
>> 
>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
>> from
>>not understanding the boundaries of your value. Or, put more
>>solicitously: sure, you can look at the world that way, but it just
>>makes everything prohibitively complicated, so why would you want to?
>> 
>>In my world, there's no such thing as a “deep copy” or a “shallow 
>> copy;”
>>there's just “copy,” which logically creates an independent version of
>>everything up to the boundaries of the value. Likewise, there's no
>>“deep value semantics” or “shallow value semantics.” 
>> 
>>Equality defines
>>value semantics, and the boundaries of an Array value always includes
>>the values of its ele

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

2016-05-07 Thread Tyler Fleming Cloutier via swift-evolution

> On May 4, 2016, at 3:50 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed May 04 2016, Matthew Johnson  > wrote:
> 
>>> On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> on Wed May 04 2016, Adrian Zubarev  wrote:
>>> 
>> 
 Not sure what to think about the enum cases inside a protocol (if AnyEnum 
 would
 even exist), it could be a nice addition to the language, but this is an 
 own
 proposal I guess.
 
 We should start by adding AnyValue protocol to which all value types
 conforms.
>>> 
>>> Having a way to constrain conformance to things with value semantics is
>>> something I've long wanted.  *However*, the approach described is too
>>> simplistic.  It's possible to build classes whose instances have value
>>> semantics (just make them immutable) and it's possible to build structs
>>> whose instances have reference semantics (just put the struct's storage
>>> in a mutable class instance that it holds as a property, and don't do
>>> copy-on-write).  
>>> 
>>> In order for something like AnyValue to have meaning, we need to impose
>>> greater order.  After thinking through many approaches over the years, I
>>> have arrived at the (admittedly rather drastic) opinion that the
>>> language should effectively outlaw the creation of structs and enums
>>> that don't have value semantics.  (I have no problem with the idea that
>>> immutable classes that want to act as values should be wrapped in a
>>> struct).  The language could then do lots of things much more
>>> intelligently, such as correctly generating implementations of equality.
>> 
>> That is a drastic solution indeed!  How would this impact things like
>> Array?  While Array itself has value semantics, the aggregate
>> obviously does not as it contains references which usually be mutated
>> underneath us.  
> 
> Value semantics and mutation can only be measured with respect to
> equality.  The definition of == for all class types would be equivalent
> to ===.  Problem solved.

Hmm, I get the feeling that I was arguing your own point back at you. Sorry, 
Dave, I’m a little slow. :)

Still, how would you generate an equality operator for a data structure that 
requires wrapper classes currently, like a LinkedList?

> 
>> Similar considerations apply to simpler wrapper structs such as Weak.
> 
> Same answer.
> 
>> My expectation is a generic aggregate such as Array would have to
>> conditionally conform to AnyValue only when Element also conforms to
>> AnyValue.
>> 
>> I’m also wondering how such a rule would be implemented while still
>> allowing for CoW structs that *do* implement value semantics, but do
>> so while using references internally.
> 
> I am not talking about any kind of statically-enforceable rule, although
> we could probably make warnings sophisticated enough to help with this.
>> 
>> If the compiler can be sophisticated enough to verify value semantics
>> statically maybe it would be better to have that mechanism be
>> triggered by conformance to AnyValue rather than for all structs and
>> enums.  Types that conform to AnyValue would receive the benefits of
>> the compiler knowing they have value semantics, while other uses of
>> structs and enums would remain valid.  Best practice would be to
>> conform structs and enums to AnyValue whenever possible.
>> 
>> Another possible advantage of this approach would be allowing
>> immutable reference types to conform to AnyValue and receive the
>> associated benefits such as the generated implementation of equality,
>> etc.
>> 
>> -Matthew
>> 
>>> 
>>> 
>>> -- 
>>> 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
> 
> -- 
> 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


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

2016-05-07 Thread Adrian Zubarev via swift-evolution
For me and my English its become hard to follow where this is going right now.

Let’s stick with my `AnyReference` and `AnyValue` protocols just for the 
example.

Do I get your intention right that we discuss here about value types that are 
constructed from their deepest only from other value types (same for 
`PureReferences`)? That’s what my understanding is for `PureValue`.

                   +-+
                   | Any |
                   +--+--+
                      |
        +-+-+
        |                           |
 +--+---+             +-++
 | AnyReference |             | AnyValue |
 +--+---+---+             +-++
    |   |                           |
+---+---+             +-+-+ 
| PureReference |             | PureValue | 
+---+             +-+-+ 
    |
+---+--+ 
| AnyObject (ObjC) | 
+--+

Side note: If SE-0083 will be accepted it might be possible that @objc will be 
dropped from `AnyObject`, correct me if I'm wrong.

I'm fine with that if that’s the case, but I'm not if one-day Swift won't allow 
anymore to mix value types with reference types.

I also don't think that `PureReference` and `PureValue` protocols could be 
implicit, but their base protocols can.

Explicit usage of these protocols on actual types:

class A: PureValue {} // won't work

class B: PureReference {
var value: OtherClass
} // can only contain only reference types (if that’s what we've been talking 
about here)

struct C: PureReference {} // won't work

struct D: PureValue {
var value: Int
} // can only contain value types, and all value types inside follow the same 
rule

Explicit usage on protocols:

protocol E: SomeOtherProtocol, PureReference {} // shouldn't work, because if 
we want to replace the `class` keyword we should at least the rule that out 
constraint protocols should sit right behind `: ` or behind 
Any(Reference/Value) which will take the first place instead.

protocol F: PureReference {
var value: SomeClass { get }
} // can only be applied to types that follow the pure reference constraint + 
SomeClass should follow the pure reference rule

protocol G: F {} // same as F

protocol H: SomeOtherProtocol, PureValue {} // same problem as with E

protocol I: PureValue {
var value: Int
func foo() -> Int
} // same rule as with class D

protocol J: PureValue {
var value: SomeClass
} // should not work

protocol K: PureValue {
func foo() -> SomeClass
} // I guess this should not work!?

protocol L: PureReference {
func foo() -> Int
} // should this work?

protocol M: PureReference {
func foo() -> SomeClass
} // like F

Implicit usage of the Any protocols:

class N {
var value: SomeValue
var anotherValue: SomeClass
func foo() -> Int
func boo() -> AClass
} // implicitly AnyReference; SomeClass can follow PureReference rule but still 
can be nested into a AnyClass or AnyValue type (same goes for SomeValue)

struct O {
var value: SomeValue
var anotherValue: SomeClass
func foo() -> Int
func boo() -> AClass
} // implicitly AnyValue; same rules as for N

Explicit protocol constrains:

protocol P: AnyValue, PureValue {} // or just PureValue

protocol Q: AnyReference, PureReference {} or just PureReference

protocol R: AnyValue {} // This protocol is problematic now, because logically 
we could apply it to a PureValue type but this shouldn’t work, just because we 
said that PureProtocols are more constrained

Now we have two options:

1. Split the Any and Pure concepts

                  +--+
                  | Pure |
                  +--+---+
                     |
       +-+-+
       |                           |
+--++            +-+-+
| PureReference |            | PureValue |
+---+            +-+-+

                  +-+
                  | Any |
                  +--+--+
                     |
       +-++
       |                          |
+--+---+            +-++
| AnyReference |            | AnyValue |
+--+            +-++

This solution feels strange. `Pure` is something like `AnyPure`.

2. Reorder Pure and Any protocols:

                  +-+
                  | Any |
                  +--+--+
                     |
       +-+-+
       |                           |
+--++            +-+-+
| PureReference |            | PureValue |
+--++            +-+-+
       |                           |
+--+---+             +-++ 
| AnyReference |             | AnyValue | 
+--+             +-++ 

protocol R: AnyValue {} // is fine now because we can't apply it to a PureValue 
anymore.

With this reorder I suggest that `PureValue` and `Pur

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

2016-05-07 Thread Tyler Fleming Cloutier via swift-evolution

> On May 5, 2016, at 8:02 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Thu May 05 2016, Matthew Johnson  > wrote:
> 
>>On May 5, 2016, at 4:59 PM, Dave Abrahams  wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev 
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value semantics
>>is
>>something I've long wanted. *However*, the approach described is too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>>Hmm. If those qualify as “value semantic” then what kind of structs 
>> and
>>enums
>>would not? A struct wrapping a mutable reference type certainly 
>> doesn’t
>>“feel”
>>value semantic to me and certainly doesn’t have the guarantees usually
>>associated with value semantics (won’t mutate behind your back, thread
>>safe,
>>etc).
>> 
>>Sure it does.
>> 
>>public struct Wrap : Equatable {
>>init(_ x: T) { self.x = x }
>>private x: T
>>}
>> 
>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>return lhs.x === rhs.x
>>}
>> 
>>I defy you to find any scenario where Wrap doesn't have value
>>semantics, whether T is mutable or not.
>> 
>>Alternately, you can look at the Array implementation. Array is a
>>struct wrapping a mutable class. It has value semantics by virtue of
>>CoW.
>> 
>> This goes back to where you draw the line as to the “boundary of the value”.
>> Wrap and Array are “value semantic” in a shallow sense and are capable of 
>> deep
>> value semantics when T is deeply value semantic. 
> 
> No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
> not understanding the boundaries of your value.  Or, put more
> solicitously: sure, you can look at the world that way, but it just
> makes everything prohibitively complicated, so why would you want to?
> 
> In my world, there's no such thing as a “deep copy” or a “shallow copy;”
> there's just “copy,” which logically creates an independent version of
> everything up to the boundaries of the value.  Likewise, there's no
> “deep value semantics” or “shallow value semantics.”  Equality defines
> value semantics, and the boundaries of an Array value always includes
> the values of its elements.  The *only* problem here is that we have no
> way to do equality comparison on some arrays because some types aren't
> Equatable.  IMO the costs of not having everything be equatable, in
> complexity-of-programming-model terms, are too high.

My point with this is, in case I was a bit rambling, if you’re going to draw 
boundaries around a value, for the purpose of copying or immutability, then 
equality should always match with those boundaries. As you 

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

2016-05-07 Thread Andrew Trick via swift-evolution

> On May 6, 2016, at 5:48 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
>> I don’t mean to imply that it is the *only* valuable
>> property. However, it I (and many others) do believe it is an extremely 
>> valuable
>> property in many cases. Do you disagree?
> 
> I think I do.  What is valuable about such a protocol?  What generic
> algorithms could you write that work on models of PureValue but don't
> work just as well on Array?

class Storage {
  var element: Int = 0
}

struct Value {
  var storage: Storage
}

func amIPure(v: Value) -> Int {
  v.storage.element = 3
  return v.storage.element
}

I (the optimizer) want to know if 'amIPure' is a pure function. The developer 
needs to tell me where the boundaries of the value lie. Does 'storage' lie 
inside the Value, or outside? If it is inside, then Value is a 'PureValue' and 
'amIPure' is a pure function. To enforce that, the developer will need to 
implement CoW, or we need add some language features.

If I know about every operation inside 'amIPure', and know where the value's 
boundary is, then I don't really need to know that 'Value' is a 'PureValue'. 
For example, I know that this function is pure without caring about 'PureValue'.

func IAmPure(v: Value, s: Storage) -> Int {
  var t = v
  t.storage = s
  return t.storage.element
}

However, I might only have summary information. I might know that the function 
only writes to memory reachable from Value. In that case, it would be nice to 
have summary information about the storage type. 'PureValue' is another way of 
saying that it does not contain references to objects outside the value's 
boundary (I would add that it cannot have a user-defined deinit). The only 
thing vague about that is that we don't have a general way for the developer to 
define the value's boundary. It certainly should be consistent with '==', but 
implementing '==' doesn't tell the optimizer anything.

Anyway, these are only optimizer concerns, and programming model should take 
precedence in these discussion. But I thought that might help.

-Andy___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-06 Thread Tyler Fleming Cloutier via swift-evolution

> On May 6, 2016, at 9:19 PM, Tyler Fleming Cloutier via swift-evolution 
>  wrote:
> 
>> 
>> On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> on Fri May 06 2016, Matthew Johnson > > wrote:
>> 
>>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>>>mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson >> > wrote:
>>> 
>>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>>>mailto:dabrah...@apple.com>> wrote:
>>> 
>>>on Thu May 05 2016, Matthew Johnson >> > wrote:
>>> 
>>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>>>mailto:dabrah...@apple.com>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson >> > wrote:
>>> 
>>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>>>mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>on Wed May 04 2016, Matthew Johnson
>>>mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>>>mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>on Wed May 04 2016, Adrian Zubarev
>>>mailto:swift-evolution@swift.org>>
>>>wrote:
>>> 
>>>Not sure what to think about the enum cases inside a
>>>protocol (if AnyEnum would
>>>even exist), it could be a nice addition to the language, but
>>>this is an own
>>>proposal I guess.
>>> 
>>>We should start by adding AnyValue protocol to which all value
>>>types
>>>conforms.
>>> 
>>>Having a way to constrain conformance to things with value semantics
>>>is
>>>something I've long wanted. *However*, the approach described is too
>>>simplistic. It's possible to build classes whose instances have
>>>value
>>>semantics (just make them immutable) and it's possible to build
>>>structs
>>>whose instances have reference semantics (just put the struct's
>>>storage
>>>in a mutable class instance that it holds as a property, and don't
>>>do
>>>copy-on-write). 
>>> 
>>>In order for something like AnyValue to have meaning, we need to
>>>impose
>>>greater order. After thinking through many approaches over the
>>>years, I
>>>have arrived at the (admittedly rather drastic) opinion that the
>>>language should effectively outlaw the creation of structs and enums
>>>that don't have value semantics. (I have no problem with the idea
>>>that
>>>immutable classes that want to act as values should be wrapped in a
>>>struct). The language could then do lots of things much more
>>>intelligently, such as correctly generating implementations of
>>>equality.
>>> 
>>>That is a drastic solution indeed! How would this impact things like
>>>Array? While Array itself has value semantics, the aggregate
>>>obviously does not as it contains references which usually be mutated
>>>underneath us. 
>>> 
>>>Value semantics and mutation can only be measured with respect to
>>>equality. The definition of == for all class types would be 
>>> equivalent
>>>to ===. Problem solved.
>>> 
>>>Similar considerations apply to simpler wrapper structs such as Weak.
>>> 
>>>Same answer.
>>> 
>>>Hmm. If those qualify as “value semantic” then what kind of structs 
>>> and
>>>enums
>>>would not? A struct wrapping a mutable reference type certainly 
>>> doesn’t
>>>“feel”
>>>value semantic to me and certainly doesn’t have the guarantees 
>>> usually
>>>associated with value semantics (won’t mutate behind your back, 
>>> thread
>>>safe,
>>>etc).
>>> 
>>>Sure it does.
>>> 
>>>public struct Wrap : Equatable {
>>>init(_ x: T) { self.x = x }
>>>private x: T
>>>}
>>> 
>>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>>return lhs.x === rhs.x
>>>}
>>> 
>>>I defy you to find any scenario where Wrap doesn't have value
>>>semantics, whether T is mutable or not.
>>> 
>>>Alternately, you can look at the Array implementation. Array is a
>>>struct wrapping a mutable class. It has value semantics by virtue of
>>>CoW.
>>> 
>>>This goes back to where you draw the line as to the “boundary of the
>>>value”.
>>>Wrap and Array are “value semantic” in a shallow sense and are 
>>> capable
>>>of deep
>>>value semantics when T is deeply value semantic. 
>>> 
>>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
>>> from
>>>not understanding the bound

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

2016-05-06 Thread Tyler Fleming Cloutier via swift-evolution

> On May 6, 2016, at 6:54 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Fri May 06 2016, Matthew Johnson  > wrote:
> 
>>On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Thu May 05 2016, Matthew Johnson  wrote:
>> 
>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>> wrote:
>> 
>>on Thu May 05 2016, Matthew Johnson  wrote:
>> 
>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson
>> wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev
>>
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value semantics
>>is
>>something I've long wanted. *However*, the approach described is too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>>Hmm. If those qualify as “value semantic” then what kind of structs 
>> and
>>enums
>>would not? A struct wrapping a mutable reference type certainly 
>> doesn’t
>>“feel”
>>value semantic to me and certainly doesn’t have the guarantees usually
>>associated with value semantics (won’t mutate behind your back, thread
>>safe,
>>etc).
>> 
>>Sure it does.
>> 
>>public struct Wrap : Equatable {
>>init(_ x: T) { self.x = x }
>>private x: T
>>}
>> 
>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>return lhs.x === rhs.x
>>}
>> 
>>I defy you to find any scenario where Wrap doesn't have value
>>semantics, whether T is mutable or not.
>> 
>>Alternately, you can look at the Array implementation. Array is a
>>struct wrapping a mutable class. It has value semantics by virtue of
>>CoW.
>> 
>>This goes back to where you draw the line as to the “boundary of the
>>value”.
>>Wrap and Array are “value semantic” in a shallow sense and are capable
>>of deep
>>value semantics when T is deeply value semantic. 
>> 
>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
>> from
>>not understanding the boundaries of your value. Or, put more
>>solicitously: sure, you can look at the world that way, but it just
>>makes everything prohibitively complicated, so why would you want to?
>> 
>>In my world, there's no such thing as a “deep copy” or a “shallow 
>> copy;”
>>there's just “copy,” which logically creates an independent version of
>>everything up to the boundaries of the value. Likewise, there's no
>>“deep value semantics” or “shallow value semantics.” 
>> 
>>Equality defines
>>value semantics, and the boundaries of an Array value always in

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

2016-05-06 Thread David Sweeris via swift-evolution
> On May 6, 2016, at 19:48, Dave Abrahams via swift-evolution 
>  wrote:
> 
> Sorry, this is the first mention I can find in the whole thread, honest.
> Oh, it was a different thread.  Joe describes it as a protocol for
> “types that represent fully self-contained values,” which is just fuzzy
> enough that everyone reading it can have his own interpretation of what
> it means.
FWIW, I've been taking it to mean a) something that can always be correctly 
copied simply by copying its memory, and b) something for which equality can be 
determined by comparing memory (or at least won't give a false positive... I 
hadn't considered the "0 == -0" kind of equality until just now).

I'm not sure that's any less fuzzy than the description you referenced, though. 
This thread has several terms that I'm not as familiar with as I should be.

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-06 Thread Dave Abrahams via swift-evolution

on Fri May 06 2016, Matthew Johnson  wrote:

> On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Thu May 05 2016, Matthew Johnson  wrote:
>
> On May 5, 2016, at 10:02 PM, Dave Abrahams
>  wrote:
>
> on Thu May 05 2016, Matthew Johnson  wrote:
>
> On May 5, 2016, at 4:59 PM, Dave Abrahams
>  wrote:
>
> on Wed May 04 2016, Matthew Johnson  wrote:
>
> On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Matthew Johnson
>  wrote:
>
> On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Adrian Zubarev
> 
> wrote:
>
> Not sure what to think about the enum cases inside a
> protocol (if AnyEnum would
> even exist), it could be a nice addition to the language, but
> this is an own
> proposal I guess.
>
> We should start by adding AnyValue protocol to which all value
> types
> conforms.
>
> Having a way to constrain conformance to things with value semantics
> is
> something I've long wanted. *However*, the approach described is too
> simplistic. It's possible to build classes whose instances have
> value
> semantics (just make them immutable) and it's possible to build
> structs
> whose instances have reference semantics (just put the struct's
> storage
> in a mutable class instance that it holds as a property, and don't
> do
> copy-on-write). 
>
> In order for something like AnyValue to have meaning, we need to
> impose
> greater order. After thinking through many approaches over the
> years, I
> have arrived at the (admittedly rather drastic) opinion that the
> language should effectively outlaw the creation of structs and enums
> that don't have value semantics. (I have no problem with the idea
> that
> immutable classes that want to act as values should be wrapped in a
> struct). The language could then do lots of things much more
> intelligently, such as correctly generating implementations of
> equality.
>
> That is a drastic solution indeed! How would this impact things like
> Array? While Array itself has value semantics, the aggregate
> obviously does not as it contains references which usually be mutated
> underneath us. 
>
> Value semantics and mutation can only be measured with respect to
> equality. The definition of == for all class types would be equivalent
> to ===. Problem solved.
>
> Similar considerations apply to simpler wrapper structs such as Weak.
>
> Same answer.
>
> Hmm. If those qualify as “value semantic” then what kind of structs 
> and
> enums
> would not? A struct wrapping a mutable reference type certainly 
> doesn’t
> “feel”
> value semantic to me and certainly doesn’t have the guarantees usually
> associated with value semantics (won’t mutate behind your back, thread
> safe,
> etc).
>
> Sure it does.
>
> public struct Wrap : Equatable {
> init(_ x: T) { self.x = x }
> private x: T
> }
>
> func == (lhs: Wrap, rhs: Wrap) -> Bool {
> return lhs.x === rhs.x
> }
>
> I defy you to find any scenario where Wrap doesn't have value
> semantics, whether T is mutable or not.
>
> Alternately, you can look at the Array implementation. Array is a
> struct wrapping a mutable class. It has value semantics by virtue of
> CoW.
>
> This goes back to where you draw the line as to the “boundary of the
> value”.
> Wrap and Array are “value semantic” in a shallow sense and are capable
> of deep
> value semantics when T is deeply value semantic. 
>
> No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes 
> from
> not understanding the boundaries of your value. Or, put more
> solicitously: sure, you can look at the world that way, but it just
> makes everything prohibitively complicated, so why would you want to?
>
> In my world, there's no such thing as a “deep copy” or a “shallow 
> copy;”
> there's just “copy,” which logically creates an independent version of
> everything up to the boundaries of the value. Likewise, there's no
> “deep value semantics” or “shallow value semantics.” 
>
> Equality defines
> value semantics, and the boundaries of an Array value always includes
> the values of its elements. The *only* problem here is that we have no
> way to do equality comparison on some arrays because some types aren't
> E

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

2016-05-06 Thread Matthew Johnson via swift-evolution

> On May 6, 2016, at 7:48 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Thu May 05 2016, Matthew Johnson  > wrote:
> 
>>On May 5, 2016, at 10:02 PM, Dave Abrahams
>> wrote:
>> 
>>on Thu May 05 2016, Matthew Johnson  wrote:
>> 
>>On May 5, 2016, at 4:59 PM, Dave Abrahams
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson
>> wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev
>>
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value semantics
>>is
>>something I've long wanted. *However*, the approach described is too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>>Hmm. If those qualify as “value semantic” then what kind of structs 
>> and
>>enums
>>would not? A struct wrapping a mutable reference type certainly 
>> doesn’t
>>“feel”
>>value semantic to me and certainly doesn’t have the guarantees usually
>>associated with value semantics (won’t mutate behind your back, thread
>>safe,
>>etc).
>> 
>>Sure it does.
>> 
>>public struct Wrap : Equatable {
>>init(_ x: T) { self.x = x }
>>private x: T
>>}
>> 
>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>return lhs.x === rhs.x
>>}
>> 
>>I defy you to find any scenario where Wrap doesn't have value
>>semantics, whether T is mutable or not.
>> 
>>Alternately, you can look at the Array implementation. Array is a
>>struct wrapping a mutable class. It has value semantics by virtue of
>>CoW.
>> 
>>This goes back to where you draw the line as to the “boundary of the
>>value”.
>>Wrap and Array are “value semantic” in a shallow sense and are capable
>>of deep
>>value semantics when T is deeply value semantic. 
>> 
>>No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
>>not understanding the boundaries of your value. Or, put more
>>solicitously: sure, you can look at the world that way, but it just
>>makes everything prohibitively complicated, so why would you want to?
>> 
>>In my world, there's no such thing as a “deep copy” or a “shallow copy;”
>>there's just “copy,” which logically creates an independent version of
>>everything up to the boundaries of the value. Likewise, there's no
>>“deep value semantics” or “shallow value semantics.” 
>> 
>>Equality defines
>>value semantics, and the boundaries of an Array value always includes
>>the values of its elements. The *only* problem here is that we have no
>>way to do equality comparison on some arrays because some types aren't
>>Equatable. IMO the costs of not ha

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

2016-05-06 Thread Dave Abrahams via swift-evolution

on Thu May 05 2016, Matthew Johnson  wrote:

> On May 5, 2016, at 10:02 PM, Dave Abrahams
>  wrote:
>
> on Thu May 05 2016, Matthew Johnson  wrote:
>
> On May 5, 2016, at 4:59 PM, Dave Abrahams
>  wrote:
>
> on Wed May 04 2016, Matthew Johnson  wrote:
>
> On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Matthew Johnson
>  wrote:
>
> On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Adrian Zubarev
> 
> wrote:
>
> Not sure what to think about the enum cases inside a
> protocol (if AnyEnum would
> even exist), it could be a nice addition to the language, but
> this is an own
> proposal I guess.
>
> We should start by adding AnyValue protocol to which all value
> types
> conforms.
>
> Having a way to constrain conformance to things with value semantics
> is
> something I've long wanted. *However*, the approach described is too
> simplistic. It's possible to build classes whose instances have
> value
> semantics (just make them immutable) and it's possible to build
> structs
> whose instances have reference semantics (just put the struct's
> storage
> in a mutable class instance that it holds as a property, and don't
> do
> copy-on-write). 
>
> In order for something like AnyValue to have meaning, we need to
> impose
> greater order. After thinking through many approaches over the
> years, I
> have arrived at the (admittedly rather drastic) opinion that the
> language should effectively outlaw the creation of structs and enums
> that don't have value semantics. (I have no problem with the idea
> that
> immutable classes that want to act as values should be wrapped in a
> struct). The language could then do lots of things much more
> intelligently, such as correctly generating implementations of
> equality.
>
> That is a drastic solution indeed! How would this impact things like
> Array? While Array itself has value semantics, the aggregate
> obviously does not as it contains references which usually be mutated
> underneath us. 
>
> Value semantics and mutation can only be measured with respect to
> equality. The definition of == for all class types would be equivalent
> to ===. Problem solved.
>
> Similar considerations apply to simpler wrapper structs such as Weak.
>
> Same answer.
>
> Hmm. If those qualify as “value semantic” then what kind of structs 
> and
> enums
> would not? A struct wrapping a mutable reference type certainly 
> doesn’t
> “feel”
> value semantic to me and certainly doesn’t have the guarantees usually
> associated with value semantics (won’t mutate behind your back, thread
> safe,
> etc).
>
> Sure it does.
>
> public struct Wrap : Equatable {
> init(_ x: T) { self.x = x }
> private x: T
> }
>
> func == (lhs: Wrap, rhs: Wrap) -> Bool {
> return lhs.x === rhs.x
> }
>
> I defy you to find any scenario where Wrap doesn't have value
> semantics, whether T is mutable or not.
>
> Alternately, you can look at the Array implementation. Array is a
> struct wrapping a mutable class. It has value semantics by virtue of
> CoW.
>
> This goes back to where you draw the line as to the “boundary of the
> value”.
> Wrap and Array are “value semantic” in a shallow sense and are capable
> of deep
> value semantics when T is deeply value semantic. 
>
> No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
> not understanding the boundaries of your value. Or, put more
> solicitously: sure, you can look at the world that way, but it just
> makes everything prohibitively complicated, so why would you want to?
>
> In my world, there's no such thing as a “deep copy” or a “shallow copy;”
> there's just “copy,” which logically creates an independent version of
> everything up to the boundaries of the value. Likewise, there's no
> “deep value semantics” or “shallow value semantics.” 
>
> Equality defines
> value semantics, and the boundaries of an Array value always includes
> the values of its elements. The *only* problem here is that we have no
> way to do equality comparison on some arrays because some types aren't
> Equatable. IMO the costs of not having everything be equatable, in
> complexity-of-programming-model terms, are too high.
>
> Thank you for clarifying the terminology for me. This is helpful. 
>
> I thin

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

2016-05-05 Thread Matthew Johnson via swift-evolution

> On May 5, 2016, at 10:02 PM, Dave Abrahams  wrote:
> 
> 
> on Thu May 05 2016, Matthew Johnson  > wrote:
> 
>>On May 5, 2016, at 4:59 PM, Dave Abrahams  wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev 
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value semantics
>>is
>>something I've long wanted. *However*, the approach described is too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>>Hmm. If those qualify as “value semantic” then what kind of structs 
>> and
>>enums
>>would not? A struct wrapping a mutable reference type certainly 
>> doesn’t
>>“feel”
>>value semantic to me and certainly doesn’t have the guarantees usually
>>associated with value semantics (won’t mutate behind your back, thread
>>safe,
>>etc).
>> 
>>Sure it does.
>> 
>>public struct Wrap : Equatable {
>>init(_ x: T) { self.x = x }
>>private x: T
>>}
>> 
>>func == (lhs: Wrap, rhs: Wrap) -> Bool {
>>return lhs.x === rhs.x
>>}
>> 
>>I defy you to find any scenario where Wrap doesn't have value
>>semantics, whether T is mutable or not.
>> 
>>Alternately, you can look at the Array implementation. Array is a
>>struct wrapping a mutable class. It has value semantics by virtue of
>>CoW.
>> 
>> This goes back to where you draw the line as to the “boundary of the value”.
>> Wrap and Array are “value semantic” in a shallow sense and are capable of 
>> deep
>> value semantics when T is deeply value semantic. 
> 
> No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
> not understanding the boundaries of your value.  Or, put more
> solicitously: sure, you can look at the world that way, but it just
> makes everything prohibitively complicated, so why would you want to?
> 
> In my world, there's no such thing as a “deep copy” or a “shallow copy;”
> there's just “copy,” which logically creates an independent version of
> everything up to the boundaries of the value.  Likewise, there's no
> “deep value semantics” or “shallow value semantics.”  
> Equality defines
> value semantics, and the boundaries of an Array value always includes
> the values of its elements.  The *only* problem here is that we have no
> way to do equality comparison on some arrays because some types aren't
> Equatable.  IMO the costs of not having everything be equatable, in
> complexity-of-programming-model terms, are too high.

Thank you for clarifying the terminology for me.  This is helpful.  

I think I may have misunderstood what you meant by “boundary of the value”.  Do 
you mean that the boundary of an Array value stops at the reference identity 
for 

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

2016-05-05 Thread Dave Abrahams via swift-evolution

on Thu May 05 2016, Matthew Johnson  wrote:

> On May 5, 2016, at 4:59 PM, Dave Abrahams  wrote:
>
> on Wed May 04 2016, Matthew Johnson  wrote:
>
> On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Matthew Johnson  wrote:
>
> On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>  wrote:
>
> on Wed May 04 2016, Adrian Zubarev 
> wrote:
>
> Not sure what to think about the enum cases inside a
> protocol (if AnyEnum would
> even exist), it could be a nice addition to the language, but
> this is an own
> proposal I guess.
>
> We should start by adding AnyValue protocol to which all value
> types
> conforms.
>
> Having a way to constrain conformance to things with value semantics
> is
> something I've long wanted. *However*, the approach described is too
> simplistic. It's possible to build classes whose instances have
> value
> semantics (just make them immutable) and it's possible to build
> structs
> whose instances have reference semantics (just put the struct's
> storage
> in a mutable class instance that it holds as a property, and don't
> do
> copy-on-write). 
>
> In order for something like AnyValue to have meaning, we need to
> impose
> greater order. After thinking through many approaches over the
> years, I
> have arrived at the (admittedly rather drastic) opinion that the
> language should effectively outlaw the creation of structs and enums
> that don't have value semantics. (I have no problem with the idea
> that
> immutable classes that want to act as values should be wrapped in a
> struct). The language could then do lots of things much more
> intelligently, such as correctly generating implementations of
> equality.
>
> That is a drastic solution indeed! How would this impact things like
> Array? While Array itself has value semantics, the aggregate
> obviously does not as it contains references which usually be mutated
> underneath us. 
>
> Value semantics and mutation can only be measured with respect to
> equality. The definition of == for all class types would be equivalent
> to ===. Problem solved.
>
> Similar considerations apply to simpler wrapper structs such as Weak.
>
> Same answer.
>
> Hmm. If those qualify as “value semantic” then what kind of structs 
> and
> enums
> would not? A struct wrapping a mutable reference type certainly 
> doesn’t
> “feel”
> value semantic to me and certainly doesn’t have the guarantees usually
> associated with value semantics (won’t mutate behind your back, thread
> safe,
> etc).
>
> Sure it does.
>
> public struct Wrap : Equatable {
> init(_ x: T) { self.x = x }
> private x: T
> }
>
> func == (lhs: Wrap, rhs: Wrap) -> Bool {
> return lhs.x === rhs.x
> }
>
> I defy you to find any scenario where Wrap doesn't have value
> semantics, whether T is mutable or not.
>
> Alternately, you can look at the Array implementation. Array is a
> struct wrapping a mutable class. It has value semantics by virtue of
> CoW.
>
> This goes back to where you draw the line as to the “boundary of the value”.
> Wrap and Array are “value semantic” in a shallow sense and are capable of deep
> value semantics when T is deeply value semantic. 

No, I'm sorry; this “deep-vs-shallow” thing is a fallacy that comes from
not understanding the boundaries of your value.  Or, put more
solicitously: sure, you can look at the world that way, but it just
makes everything prohibitively complicated, so why would you want to?

In my world, there's no such thing as a “deep copy” or a “shallow copy;”
there's just “copy,” which logically creates an independent version of
everything up to the boundaries of the value.  Likewise, there's no
“deep value semantics” or “shallow value semantics.”  Equality defines
value semantics, and the boundaries of an Array value always includes
the values of its elements.  The *only* problem here is that we have no
way to do equality comparison on some arrays because some types aren't
Equatable.  IMO the costs of not having everything be equatable, in
complexity-of-programming-model terms, are too high.

> Both have their place, but the maximum benefit of value semantics
> (purity) 

I don't know what definition of purity you're using.  The only one I
know of applies to functions and implies no side effects.  In that
world, there is no mutation and value semantics is equivalent to
reference semantics.

> is derived from deep value semantics. This is when there is no
> possibility of shared mutable state. This is

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

2016-05-05 Thread Matthew Johnson via swift-evolution

> On May 5, 2016, at 4:59 PM, Dave Abrahams  wrote:
> 
> 
> on Wed May 04 2016, Matthew Johnson  > wrote:
> 
>>On May 4, 2016, at 5:50 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Matthew Johnson  wrote:
>> 
>>On May 4, 2016, at 1:29 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Wed May 04 2016, Adrian Zubarev 
>>wrote:
>> 
>>Not sure what to think about the enum cases inside a
>>protocol (if AnyEnum would
>>even exist), it could be a nice addition to the language, but
>>this is an own
>>proposal I guess.
>> 
>>We should start by adding AnyValue protocol to which all value
>>types
>>conforms.
>> 
>>Having a way to constrain conformance to things with value 
>> semantics
>>is
>>something I've long wanted. *However*, the approach described is 
>> too
>>simplistic. It's possible to build classes whose instances have
>>value
>>semantics (just make them immutable) and it's possible to build
>>structs
>>whose instances have reference semantics (just put the struct's
>>storage
>>in a mutable class instance that it holds as a property, and don't
>>do
>>copy-on-write). 
>> 
>>In order for something like AnyValue to have meaning, we need to
>>impose
>>greater order. After thinking through many approaches over the
>>years, I
>>have arrived at the (admittedly rather drastic) opinion that the
>>language should effectively outlaw the creation of structs and 
>> enums
>>that don't have value semantics. (I have no problem with the idea
>>that
>>immutable classes that want to act as values should be wrapped in 
>> a
>>struct). The language could then do lots of things much more
>>intelligently, such as correctly generating implementations of
>>equality.
>> 
>>That is a drastic solution indeed! How would this impact things like
>>Array? While Array itself has value semantics, the aggregate
>>obviously does not as it contains references which usually be mutated
>>underneath us. 
>> 
>>Value semantics and mutation can only be measured with respect to
>>equality. The definition of == for all class types would be equivalent
>>to ===. Problem solved.
>> 
>>Similar considerations apply to simpler wrapper structs such as Weak.
>> 
>>Same answer.
>> 
>> Hmm. If those qualify as “value semantic” then what kind of structs and enums
>> would not? A struct wrapping a mutable reference type certainly doesn’t 
>> “feel”
>> value semantic to me and certainly doesn’t have the guarantees usually
>> associated with value semantics (won’t mutate behind your back, thread safe,
>> etc).
> 
> Sure it does.
> 
> public struct Wrap : Equatable {
>   init(_ x: T) { self.x = x }
>   private x: T
> }
> 
> func == (lhs: Wrap, rhs: Wrap) -> Bool {
>   return lhs.x === rhs.x
> }
> 
> I defy you to find any scenario where Wrap doesn't have value
> semantics, whether T is mutable or not.
> 
> Alternately, you can look at the Array implementation.  Array is a
> struct wrapping a mutable class.  It has value semantics by virtue of
> CoW.

This goes back to where you draw the line as to the “boundary of the value”.  
Wrap and Array are “value semantic” in a shallow sense and are capable of deep 
value semantics when T is deeply value semantic.  Both have their place, but 
the maximum benefit of value semantics (purity) is derived from deep value 
semantics.  This is when there is no possibility of shared mutable state.  This 
is an extremely important property.


let t = MyClass()
foo.acceptWrapped(Wrap(t))
t.mutate()

In this example, foo had better not depend on the wrapped instance not getting 
mutated.

> 
>>My expectation is a generic aggregate such as Array would have to
>>conditionally conform to AnyValue only when Element also conforms to
>>AnyValue.
>> 
>>I’m also wondering how such a rule would be implemented while still
>>allowing for CoW structs that *do* implement value semantics, but do
>>so while using references internally.
>> 
>>I am not talking about any kind of statically-enforceable rule, although
>>we could probably make warnings sophisticated enough to help with this.
>> 
>> You said the you have arrived at the opinion that the language should
>> “effectively outlaw” structs and enums that do not have value semantics. That
>> sounded like static enforcement to me. 
> 
> The language outlaws certain kinds of inout aliasing without providing static
> e

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

2016-05-05 Thread David Sweeris via swift-evolution

> On May 5, 2016, at 6:55 PM, Dave Abrahams  wrote:
> 
> 
> on Thu May 05 2016, David Sweeris  wrote:
> 
>> I meant leave `struct` and `enum` the way they are, and introduce a
>> `different_struct` and `different_enum` (placeholder names, of course)
>> which enforced the “no reference-semantics” rules.
> 
> I would be pretty strongly opposed to that.  That's almost the opposite
> of what I'm proposing.
> 
>> I’m inclined to think we should adopt your “no reference-semantics”
>> rule, but I’m not entirely sure what the impact would be. Adding new
>> types side-steps the issue, at the cost of increasing the complexity
>> of the language/compiler. I’m unsure if that'd be a worth-while
>> trade-off.
> 
> The whole point of my proposal is to simplify the model.
Oh, ok… I think I got your ends and your means backwards in my head.

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-05 Thread Dave Abrahams via swift-evolution

on Thu May 05 2016, David Sweeris  wrote:

>> On May 5, 2016, at 5:01 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Wed May 04 2016, David Sweeris  wrote:
>> 
>
 On May 4, 2016, at 13:29, Dave Abrahams via swift-evolution 
  wrote:
 
 In order for something like AnyValue to have meaning, we need to impose
 greater order.  After thinking through many approaches over the years, I
 have arrived at the (admittedly rather drastic) opinion that the
 language should effectively outlaw the creation of structs and enums
 that don't have value semantics.  (I have no problem with the idea that
 immutable classes that want to act as values should be wrapped in a
 struct).  The language could then do lots of things much more
 intelligently, such as correctly generating implementations of
 equality. 
>>> 
>>> You mean that a struct's properties would have to have value
>>> semantics, too? 
>> 
>> Either that, or you'd have to implement CoW, or you'd not use the
>> storage behind any properties that were references in a way that affects
>> value semantics.
>> 
>>> I think I'm okay with that, especially if it's done through new types
>>> of structs/enums.
>> 
>> New types of structs/enums?  What does that mean?
> I meant leave `struct` and `enum` the way they are, and introduce a
> `different_struct` and `different_enum` (placeholder names, of course)
> which enforced the “no reference-semantics” rules.

I would be pretty strongly opposed to that.  That's almost the opposite
of what I'm proposing.

> I’m inclined to think we should adopt your “no reference-semantics”
> rule, but I’m not entirely sure what the impact would be. Adding new
> types side-steps the issue, at the cost of increasing the complexity
> of the language/compiler. I’m unsure if that'd be a worth-while
> trade-off.

The whole point of my proposal is to simplify the model.

-- 
Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-05 Thread David Sweeris via swift-evolution

> On May 5, 2016, at 5:01 PM, Dave Abrahams  wrote:
> 
> 
> on Wed May 04 2016, David Sweeris  wrote:
> 
>>> On May 4, 2016, at 13:29, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> In order for something like AnyValue to have meaning, we need to impose
>>> greater order.  After thinking through many approaches over the years, I
>>> have arrived at the (admittedly rather drastic) opinion that the
>>> language should effectively outlaw the creation of structs and enums
>>> that don't have value semantics.  (I have no problem with the idea that
>>> immutable classes that want to act as values should be wrapped in a
>>> struct).  The language could then do lots of things much more
>>> intelligently, such as correctly generating implementations of
>>> equality. 
>> 
>> You mean that a struct's properties would have to have value
>> semantics, too? 
> 
> Either that, or you'd have to implement CoW, or you'd not use the
> storage behind any properties that were references in a way that affects
> value semantics.
> 
>> I think I'm okay with that, especially if it's done through new types
>> of structs/enums.
> 
> New types of structs/enums?  What does that mean?
I meant leave `struct` and `enum` the way they are, and introduce a 
`different_struct` and `different_enum` (placeholder names, of course) which 
enforced the “no reference-semantics” rules.

I’m inclined to think we should adopt your “no reference-semantics” rule, but 
I’m not entirely sure what the impact would be. Adding new types side-steps the 
issue, at the cost of increasing the complexity of the language/compiler. I’m 
unsure if that'd be a worth-while trade-off.

- Dave Sweeris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-05-05 Thread Dave Abrahams via swift-evolution

on Wed May 04 2016, David Sweeris  wrote:

>> On May 4, 2016, at 13:29, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> In order for something like AnyValue to have meaning, we need to impose
>> greater order.  After thinking through many approaches over the years, I
>> have arrived at the (admittedly rather drastic) opinion that the
>> language should effectively outlaw the creation of structs and enums
>> that don't have value semantics.  (I have no problem with the idea that
>> immutable classes that want to act as values should be wrapped in a
>> struct).  The language could then do lots of things much more
>> intelligently, such as correctly generating implementations of
>> equality. 
>
> You mean that a struct's properties would have to have value
> semantics, too? 

Either that, or you'd have to implement CoW, or you'd not use the
storage behind any properties that were references in a way that affects
value semantics.

> I think I'm okay with that, especially if it's done through new types
> of structs/enums.

New types of structs/enums?  What does that mean?

-- 
Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


  1   2   >