[swift-evolution] [Draft][Proposal] Formalized Ordering

Matthew Johnson matthew at anandabits.com
Fri Jul 22 21:19:32 CDT 2016


> On Jul 22, 2016, at 9:12 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
> On Fri, Jul 22, 2016 at 9:09 PM, Jaden Geller <jaden.geller at gmail.com <mailto:jaden.geller at gmail.com>> wrote:
>> 1. NaN != NaN and +0 == -0 [what the traditional comparison operators are constrained to do]
>> 2. NaN == NaN, +0 == -0, and the same number encoded different ways compare equal
>> 3. NaN == NaN, +0 != -0, and the same number encoded different ways compare not equal
> 
> 
> Though it seems super confusing that a language have THREE ways to compare values, that does almost seem necessary here. Do we actually need an operator that performs #3? I understand that that is equality under total ordering, but couldn't users just write `(a <=> b) == .same` if they want that?
> 
> For floating point types, I think `===` shouldn't be #3. From a practical standpoint, no one ever wants that definition unless they are ordering things. Whereas you'd want #2 for things like `.index(of:)` and #1 for the traditional comparison operators.

However, we have to introduce a new notion of identity for floating point types if `===` isn’t #3.  Floating points are tricky enough already.  Is that really a good thing?

Further, it encodes three separate meanings of equality in the protocols.  We should avoid that if we can.

It feels like maybe the right solution is floating point specific algorithm overloads.  It doesn’t seem like too big a surprise that this is the case when you really dig into the details.

>  
> 
>> On Jul 22, 2016, at 7:04 PM, Xiaodi Wu <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
>> 
>> On Fri, Jul 22, 2016 at 8:57 PM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>> 
>>> On Jul 22, 2016, at 8:54 PM, Xiaodi Wu via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> On Fri, Jul 22, 2016 at 8:52 PM, Jaden Geller via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> "The totalOrder predicate will order these cases, and it also distinguishes between different representations of NaNs and between the same decimal floating point number encoded in different ways."
>>> - [Wikipedia](https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate <https://en.wikipedia.org/wiki/IEEE_floating_point#Total-ordering_predicate>)
>>> 
>>> Sounds like `===` should not return `true` for zeros of different signs, then.
>>> 
>>> Fair enough; the result of that will be, as Pyry noted above, that:
>>> 
>>> ```
>>> [-0.0, 1.0, .nan, 0.0].firstIndex(of: 0.0) //=> 3, not 0
>>> ```
>> 
>> Maybe we need floating point specific implementations of some algorithms to resolve this problem?
>> 
>> It doesn’t seem like there is a way to provide the semantics required by generic algorithms and still provide the expected behavior for floating point values.  
>> 
>> Well, what I'm trying to say is that generic algorithms such as `index(of:)` require only an equivalence relation. For floating point types, there are three ways to slice it:
>> 
>> 1. NaN != NaN and +0 == -0 [what the traditional comparison operators are constrained to do]
>> 2. NaN == NaN, +0 == -0, and the same number encoded different ways compare equal
>> 3. NaN == NaN, +0 != -0, and the same number encoded different ways compare not equal
>> 
>> Both #2 and #3 can fall out of valid equivalence relations; if `===` behaved like #2 for FloatingPoint types, then generic algorithms work just fine. If we insist on using a total ordering defined by `<=>` all the time, then we've got problems.
>> 
>>  
>> 
>>> 
>>>> On Jul 22, 2016, at 6:48 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>> 
>>>> on Fri Jul 22 2016, Jaden Geller <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> 
>>>>>> For floating point, I'd hope that `a === b` if `(a <=> b) == .same`
>>>>>> *but not iff*. This is to satisfy IEEE 754: "Comparisons shall
>>>>>> ignore the sign of zero (so +0 = −0)".
>>>>> 
>>>>> I don't see why both `(+0) === (-0)` and `(+0) <=> (-0)` can't return
>>>>> `true` and `.same`, respectively. This doesn't break the total
>>>>> ordering of values. `===` doesn't do raw memory comparison. They're
>>>>> "identical", so it ought to return `true`.
>>>> 
>>>> It ought to do whatever IEEE-754 specifies that its total ordering test
>>>> does.  That is, IEEE-754 gets to decide whether the difference between
>>>> +0 and -0 is “essential” to IEEE-754 floating point types, or not.
>>>> 
>>>>> 
>>>>>> On Jul 22, 2016, at 6:37 PM, Xiaodi Wu via swift-evolution
>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>> 
>>>>>> On Fri, Jul 22, 2016 at 8:20 PM, Dave Abrahams via swift-evolution
>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>> wrote:
>>>>>> 
>>>>>> on Fri Jul 22 2016, Daniel Duan <daniel-AT-duan.org <http://daniel-at-duan.org/>> wrote:
>>>>>> 
>>>>>>>> On Jul 22, 2016, at 3:00 PM, Dave Abrahams via swift-evolution
>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> on Fri Jul 22 2016, Daniel Duan
>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>>
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>> 
>>>>>>>>>> On Jul 22, 2016, at 11:05 AM, Dave Abrahams via swift-evolution
>>>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>>
>>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> on Thu Jul 21 2016, Duan
>>>>>>>>> 
>>>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>>>
>>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>>> Great proposal. I want to second that areSame may mislead user to
>>>>>>>>>>> think this is about identity.
>>>>>>>>>>> 
>>>>>>>>>>> I like areEquivalent() but there may be better names.
>>>>>>>>>> 
>>>>>>>>>> It really *is* about identity as I posted in a previous message.  But
>>>>>>>>>> that doesn't change the fact that areEquivalent might be a better name.
>>>>>>>>>> It's one of the things we considered; it just seemed long for no real
>>>>>>>>>> benefit.
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> If the addresses of the arguments aren’t being used, then we don’t consider
>>>>>>>>> them part of their *identity*. I can follow this logic. My fear is most users
>>>>>>>>> won’t make this leap on their own and get the same initial impression as I did.
>>>>>>>>> It's entirely possible this fear is unfounded. Some educated bikesheding
>>>>>>>>> wouldn't hurt here IMO :)
>>>>>>>> 
>>>>>>>> Well, it's still a very real question whether we ought to have the
>>>>>>>> additional API surface implied by areSame, or wether we should collapse
>>>>>>>> it with ===.
>>>>>>>> 
>>>>>>> 
>>>>>>> To spell this out (because I had to think about it for a second): === will be derived from
>>>>>>> <=>,
>>>>>>> but also becomes default implementation for ==, which remains open for
>>>>>>> customization.
>>>>>> 
>>>>>> I was imagining roughly this (untested):
>>>>>> 
>>>>>>  /// Two references are identical if they refer to the same
>>>>>>  /// instance.
>>>>>>  ///
>>>>>>  /// - Note: Classes with a more-refined notion of “identical”
>>>>>>  ///   should conform to `Identifiable` and implement `===`.
>>>>>>  func ===(lhs: AnyObject, rhs: AnyObject) -> Bool {
>>>>>>    ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
>>>>>>  }
>>>>>> 
>>>>>>  /// Supports testing that two values of `Self` are identical
>>>>>>  ///
>>>>>>  /// If `a` and `b` are of type `Self`, `a === b` means that
>>>>>>  /// `a` and `b` are interchangeable in most code.  A conforming
>>>>>>  /// type can document that specific observable characteristics
>>>>>>  /// (such as the `capacity` of an `Array`) are inessential and
>>>>>>  /// thus not to be considered as part of the interchangeability
>>>>>>  /// guarantee.
>>>>>>  ///
>>>>>>  /// - Requires: `===` induces an equivalence relation over
>>>>>>  ///   instances.
>>>>>>  /// - Note: conforming types will gain an `==` operator that
>>>>>>  ///   forwards to `===`.
>>>>>>  /// - Note: Types that require domain-specific `==`
>>>>>>  ///   implementations with different semantics (e.g. floating
>>>>>>  ///   point) should define a more-specific overload of `==`,
>>>>>>  ///   which will be used in contexts where the static type is
>>>>>>  ///   known to the compiler.
>>>>>>  /// - Note: Generic code should usually use `==` to compare
>>>>>>  ///   conforming instances; that will always dispatch to `===`
>>>>>>  ///   and will be unaffected by more specific overloads of
>>>>>>  ///   `==`.
>>>>>>  protocol Identifiable { // née Equatable name is negotiable
>>>>>>    func ===(_: Self, _: aSelf) -> Bool
>>>>>>  }
>>>>>> 
>>>>>>  /// Default definition of `==` for Identifiable types.
>>>>>>  func ==<T: Identifiable>(lhs: T, rhs: T) -> Bool {
>>>>>>    return lhs === rhs
>>>>>>  }
>>>>>> 
>>>>>>  /// Conforming types have a default total ordering.
>>>>>>  ///
>>>>>>  /// If `a` and `b` are of type `Self`, `a <=> b` means that
>>>>>>  /// `a` and `b` are interchangeable in most code.  A conforming
>>>>>>  /// type can document that specific observable characteristics
>>>>>>  /// (such as the `capacity` of an `Array`) are inessential and
>>>>>>  /// thus not to be considered as part of the interchangeability
>>>>>>  /// guarantee.
>>>>>>  ///
>>>>>>  /// - Requires: `<=>` induces a total ordering over
>>>>>>  ///   instances.
>>>>>>  /// - Requires: the semantics of `<=>` are  consistent with
>>>>>>  ///   those of `===`.  That is, `(a <=> b) == .equivalent`
>>>>>>  ///   iff `a === b`.
>>>>>> 
>>>>>> For floating point, I'd hope that `a === b` if `(a <=> b) == .same` *but not iff*. This is to satisfy IEEE 754: "Comparisons shall ignore the sign of zero (so +0 = −0)".
>>>>>> 
>>>>>>  /// - Note: conforming types will gain `<`, `<=`, `>`, and `>=`
>>>>>>  ///   operators defined in terms of `<=>`.
>>>>>>  /// - Note: Types that require domain-specific `<`, etc.
>>>>>>  ///   implementations with different semantics (e.g. floating
>>>>>>  ///   point) should define more-specific overloads of those
>>>>>>  ///   operators, which will be used in contexts where the
>>>>>>  ///   static type is known to the compiler.
>>>>>>  /// - Note: Generic code can freely use `<=>` or the traditional
>>>>>>  ///   comparison operators to compare conforming instances;
>>>>>>  ///   the result will always be supplied by `<=>`
>>>>>>  ///   and will be unaffected by more specific overloads of
>>>>>>  ///   the other operators.
>>>>>>  protocol Comparable : Identifiable {
>>>>>>    func <=> (lhs: Self, rhs: Self) -> Ordering
>>>>>>  }
>>>>>> 
>>>>>>  /// Default implementations of `<`, `<=`, `>`, and `>=`.
>>>>>>  extension Comparable {
>>>>>>    static func <(lhs: Self, rhs: Self) -> Bool {
>>>>>>      return (lhs <=> rhs) == .ascending
>>>>>>    }
>>>>>>    static func <=(lhs: Self, rhs: Self) -> Bool {
>>>>>>      return (rhs <=> lhs) != .ascending
>>>>>>    }
>>>>>>    static func >(lhs: Self, rhs: Self) -> Bool {
>>>>>>      return (lhs <=> rhs) == .descending
>>>>>>    }
>>>>>>    static func >=(lhs: Self, rhs: Self) -> Bool {
>>>>>>      return (rhs <=> lhs) != .descending
>>>>>>    }
>>>>>>  }
>>>>>> 
>>>>>>> I like this idea. If we keep === as a separate thing, now users have 3 “opportunities” to define
>>>>>>> equality. The must be few, if any, use cases for this.
>>>>>>> 
>>>>>>> Would love to see if anyone on the list can give us an example. Otherwise we should make
>>>>>>> areSame === again™!
>>>>>>> 
>>>>>>>>> 
>>>>>>>>>>> Daniel Duan
>>>>>>>>>>> Sent from my iPhone
>>>>>>>>>>> 
>>>>>>>>>>>> On Jul 21, 2016, at 6:32 PM, Robert Widmann via swift-evolution
>>>>>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>>>>>> wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>>> On Jul 21, 2016, at 6:19 PM, Xiaodi Wu
>>>>>>>>>>>>> <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>
>>>>>>>>>>>>> <mailto:xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>>>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> This is nice. Is `areSame()` being proposed because static `==` is
>>>>>>>>>>>>> the status quo and you're trying to make the point that `==` in the
>>>>>>>>>>>>> future need not guarantee the same semantics?
>>>>>>>>>>>> 
>>>>>>>>>>>> Yep!  Equivalence and equality are strictly very different things.
>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Nit: I think the more common term in stdlib would be
>>>>>>>>>>>>> `areEquivalent()`. Do you think `same` in that context (independent
>>>>>>>>>>>>> of the word "ordering") might erroneously suggest identity?
>>>>>>>>>>>> 
>>>>>>>>>>>> There is room for improvement here.  Keep ‘em coming.
>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> On Thu, Jul 21, 2016 at 8:11 PM, Robert Widmann via
>>>>>>>>>>>>>> swift-evolution
>>>>>>>>>>>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>> Hello Swift Community,
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Harlan Haskins, Jaden Geller, and I have been working on a
>>>>>>>>>>>>>> proposal to clean up the semantics of ordering relations in the
>>>>>>>>>>>>>> standard library.  We have a draft that you can get as a gist.
>>>>>>>>>>>>>> Any feedback you might have about this proposal helps - though
>>>>>>>>>>>>>> please keeps your comments on Swift-Evolution and not on the gist.
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> Cheers,
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> ~Robert Widmann
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> --
>>>>>>>>>> Dave
>>>>>>>>>> 
>>>>>>>>>> _______________________________________________
>>>>>>>>>> swift-evolution mailing list
>>>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>>
>>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> swift-evolution mailing list
>>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>>
>>>>>>>>> 
>>>>>>>> 
>>>>>>>> --
>>>>>>>> Dave
>>>>>>>> 
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>>
>>>>>> 
>>>>>> --
>>>>>> Dave
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>> 
>>>> -- 
>>>> Dave
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160722/e354a381/attachment.html>


More information about the swift-evolution mailing list