> On May 20, 2016, at 7:40 PM, Brent Royal-Gordon via swift-evolution
> <[email protected]> wrote:
>
>> The Any-class requirement could replace the current `AnyObject` protocol
>> with a typealias like this: `typealias AnyObject = Any<class>`
>>
>> Assume Swift would introduce Any-struct and Any-enum requirement one day.
>> How would one name a typealias for these, where `AnyClass` means
>> `AnyObject.Type`?
>>
>> I suggest we drop the current `AnyClass` and rename `AnyObject` to
>> `AnyClass`. If one would need the old `AnyClass` behavior it will become
>> `AnyClass.Type`.
>
> I propose that we deprecate `AnyObject` in favor of `Any<class>`. No
> typealias, just directly using `Any<>`. We would also deprecate `AnyClass` in
> favor of `Any<class>.Type`. (Presumably we would do this by providing
> `AnyObject` and `AnyClass` typealiases in Swift 3, but marking them as
> deprecated.)
>
> I like this approach because it exposes people to `Any<>` and more quickly
> gets them to see how it's connected to a protocol declaration's conformance
> list. They might then guess that `Any<>` has other capabilities from that
> list, like the ability to handle multiple protocols.
>
>> In the future we could have typealiases like this, which are more clear:
>>
>> `typealias AnyClass = Any<class>`
>> `typealias AnyStruct = Any<struct>`
>> `typealias AnyEnum = Any<enum>`
>
> Even in the long term, I don't see any good reason to support `Any<struct>`
> vs. `Any<enum>`. There is no semantic distinction* between a struct and an
> enum; you can always implement something enum-y using a struct with a mode
> field, or something struct-y using an enum with associated values. `Bool`,
> for instance, was once an enum and was changed to a struct for implementation
> reasons; this change made no difference to how it was used.
>
> Now, there *is* a semantic distinction between struct/enum and class—one is a
> value type, the other is a reference type. To support that distinction, it
> might make sense to support an `Any<value>` or `Any<!class>` syntax. Again, I
> would prefer to use the raw `Any<>` syntax, though, not a typealias.
You can implement reference types with value semantics and value types with
reference semantics. Until the compiler can verify value semantics I am not
sure there is a benefit to `any<value>`. The semantic distinction is what is
important. There has been discussion about strengthening the “value type ==
value semantics” and “reference type == reference semantics” relations but that
hasn’t yet moved beyond talk.
>
> (I've read the arguments about pure vs. non-pure value type conformances and
> I'm not convinced. It is always possible to nominally "conform" to a protocol
> in a way that actually undermines its guarantees; for example, you could
> implement `RangeReplaceableCollection.remove(at:)` as a no-op. The compiler
> cannot reject all invalid conformances; it can only reject ones which it can
> trivially show are invalid, because for instance they do not even attempt to
> provide a required method. Similarly, the compiler may not be able to prove
> you are providing value semantics, but it *can* reject conformances of
> reference types to a protocol requiring value semantics, since those cannot
> possibly be valid conformances.
Immutable reference types actually *can* provide valid value semantics (at
least as long as as they can provide their own implementation of `==` which I
believe Dave A is arguing against).
There is a big difference between semantics that the compiler *could* but *does
not yet* verify and semantics that simply cannot be verified.
>
> Incidentally, I am not convinced that it *ever* makes sense to have a
> mutating protocol which does not specify either value or reference semantics.
> The only intentional Stdlib examples I'm aware of are `IteratorProtocol` and
> `OutputStream`, and I think both of those should be reference-only.
>
> (On the other hand, it might make sense to be able to mark a struct or enum
> as "this is actually a reference type". For instance, if you import libc,
> UnsafeMutablePointer<FILE> is essentially a reference type. But on the
> gripping hand, you *could*, and perhaps should, just wrap it in a class,
> either through importer magic or a manually-created type. That would permit
> you to conform it to reference-typed mutating protocols.))
This is a good example of why the semantics aren’t so simple.
>
>
>
> * There *are* some distinctions, particularly in pattern matching, but
> protocols can't model them anyway. Incidentally, it is not possible to
> satisfy static property/method requirements with cases, but it probably
> should be:
>
> protocol OptionalProtocol {
> associatedtype W
> static var none: Self { get }
> static func some(value: W) -> Self
> }
> extension Optional: OptionalProtocol {
> typealias W = Wrapped
> }
I think there was discussion at some point about introducing enum case
requirements into protocols. But that is mostly tangential to this discussion.
>
>
> --
> Brent Royal-Gordon
> Architechies
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution