[swift-evolution] [Oversight] Reference types allow mutating methods through generics
dabrahams at apple.com
Thu May 5 14:58:49 CDT 2016
on Thu May 05 2016, Joe Groff <jgroff-AT-apple.com> wrote:
>> On May 5, 2016, at 10:03 AM, Dave Abrahams <dabrahams at apple.com> wrote:
>> on Thu May 05 2016, Joe Groff <jgroff-AT-apple.com> wrote:
>>>> On May 5, 2016, at 8:56 AM, Dave Abrahams <dabrahams at apple.com> wrote:
>>>> on Wed May 04 2016, Joe Groff <jgroff-AT-apple.com> wrote:
>>>>>> On May 4, 2016, at 5:28 AM, T.J. Usiyan via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>> Something about your first paragraph reminded me of a question I've
>>>>>> had for a while. Is there a reasoning behind not being able to
>>>>>> restrict a protocol to value types? One way that this might be
>>>>>> workable is if we could overload protocols for Value vs for
>>>>> I'm not totally comfortable with this, because references are a kind
>>>>> of value.
>>>> We're using the word “value” in 3 different ways now. If we don't sort
>>>> them out, this is going to become impossible to resolve. So let me
>>>> propose some terms:
>>>> 1. Joe's sense, i.e. the compiler-implementation-level sense, in which a
>>>> value of type T is essentially what an UnsafePointer<T> points at.
>>>> In this sense, a variable of any type T “has a value.” Even though
>>>> it's not strictly correct (since the term really applies to
>>>> expressions), I propose “rvalue” for this one.
>>>> 2. The “value types vs reference types” sense, where every type falls
>>>> into one of two crisp buckets based on how it's declared. I propose
>>>> we always say “reference type” or “value type” for this one.
>>>> 3. The “value semantics vs reference semantics” sense, where a type's
>>>> category depends on how it is implemented, and it's possible (though
>>>> inadvisable) to fall outside either bucket. This is the only
>>>> interesting category when you're discussing protocols and
>>>> constraints, and doesn't have any intrinsic relationship to sense
>>>> #2. I propose we always say “value semantics” or “reference
>>>> semantics” for this one.
>>> I claim that my sense is the same as #2. A reference has all the
>>> properties of a value-type value; it has the additional ability to be
>>> used as a handle to access independent program state. Int isn't any
>>> less of a value because it can be used to reference values in an
>> It's less of a value in sense #2 because
>> x as Any as? AnyObject
>> is always nil for a value in sense #2.
>>> Rather than try to break the world down according to categories of
>>> types, I think it's more effective to look at the semantics of
>>> *operations*. So called "reference types" have value semantics
>>> operations too;
>> Please define the term “value semantics operation.” I wager there is no
>> such thing.
> A mutating operation with no other side effects than modifying the values of its 'inout' parameters.
>>> reassigning a class reference, '+='-ing a pointer,
>> A pointer is a value type in every sense of the word.
>>> and adding or removing elements from an Array of references are all
>>> operations that mutate only the value being operated on, even though
>>> none of these types are strictly "value types".
>> Now you're really blending meanings, or at least being very fuzzy. Your
>> Array of references has a sense #1 value that might not even be altered
>> when you change the elements in the array. It is a sense #2 value by
>> language rules. It almost has sense #3 value semantics but for our
>> inability to compare it with "==", because we don't implicitly get "=="
>> defined in terms of "===" for all classes.
>> Saying something has value semantics is meaningless without a way to
>> determine equivalence that respects the boundaries of the value. The
>> *whole point* of value semantics is that initialization, assignment,
>> parameter passing, and returning all create *independent* instances, with
>> no observable shared state, and that can be read and mutated
>> concurrently in different threads. To even test that, you need to nail
>> down what it means for a value to change, and for that, you need an
>> equality comparison.
> What I'm trying to say is that there are "boundaries of the value" for
> everything in our system. For class references, that boundary happens
> to only include the reference itself.
I would agree that there are *potential* “boundaries of the value” for
everything in our system. Up to now, there has been no general
agreement that the default “boundaries of the value” for references stop
at the reference's own bits, and that mutable classes can't have an "=="
that reaches beyond those bits. Until we reach such agreement, I don't
think there's any reasonable way to argue that any of the three
categories I listed are the same. And I think we need those categories
in order to create that agreement.
More information about the swift-evolution