[swift-evolution] [Pitch] Rename `AnyObject` to `AnyClass` and drop current `AnyClass`

Dave Abrahams dabrahams at apple.com
Sun May 22 15:51:14 CDT 2016

on Sun May 22 2016, Matthew Johnson <swift-evolution at swift.org> wrote:

>> On May 22, 2016, at 1:23 PM, Dave Abrahams via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> on Fri May 20 2016, Matthew Johnson
>> <swift-evolution at swift.org
>> <mailto:swift-evolution at swift.org>>
>> wrote:
>>>> On May 20, 2016, at 7:40 PM, Brent Royal-Gordon via
>>>> swift-evolution
>>>> <swift-evolution at swift.org> 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).
>> I am not making a strong argument against that, though it might be
>> reasonable.  I am mostly arguing in favor of a default definition of ==
>> for all reference types that is equivalent to ===.
> Sorry I misunderstood.  To make sure I understand clearly: you’re not
> arguing against reference types with value semantics, just that we
> should allow reference semantics to be assumed unless custom equality
> is implemented.  Is that correct?

I don't view an immutable class with custom equality as problematic in
principle, but if dropping that capability would allow us to simplify
the programming model, I would do so in a heartbeat.  I haven't had the
chance to consider all the implications yet, but—at least until someone
can demonstrate that we really custom == for classes—we should be open
to the idea as we consider the value semantics story.


More information about the swift-evolution mailing list