[swift-evolution] [Proposal] Disallow redundant `Any<...>` constructs

Brent Royal-Gordon brent at architechies.com
Fri May 20 20:16:21 CDT 2016

>> * I think `Any` (without parameters) should be uppercase, and I don't think we should have both `Any` and `any<>` or `any`. Death to the typealias!
> Why do you think this?  `any<>` (or `Any<>`) is replacing `protocol<>`.  `protocol` is a keyword, so following the convention you shared it should be all lowercase.  Aside from that, it behaves differently than a user-defined type (which would be uppercase).

What I'm saying is that I strongly prefer this:

	func print(_ values: Any..., separator: String, terminator: String)

To this:

	func print(_ values: any..., separator: String, terminator: String)

And that I think it would be confusing and unnecessarily duplicative to have both `Any` and `any<...>` in the language, differing only in capitalization.

>> * If type-erasing structs like `AnySequence` are eventually subsumed by this syntax, I would prefer they be called `Any<Sequence>` instead of `any<Sequence>`.
> Are you arguing this because they are types?  They are currently structs.  If they were subsumed by this proposal they most definitely would not be structs.

No—what I'm saying is that, in a choice between `Any<Sequence>` and `any<Sequence>`, I would prefer to use `Any<Sequence>`. The `Any<…>` here is acting like a type (actually, it *is* a type, just a slightly special type) and it should be capitalized like a type.

> If it’s just syntax you’re concerned with, we could add a typealias:
> typealias AnySequence<T> = any<Sequence where .Iterator.Element == T>

This is quite the opposite of what I would want—I would much prefer that people use `Any<Sequence>` directly rather than an `AnySequence` typedef. This will help them learn that the feature is there for other situations, like `Any<Equatable>`.

In general, I believe it's a good idea to expose `Any<…>` directly, rather than hiding it behind a typealias. For the cost of a few extra characters, we expose a lot of power and flexibility directly to the user. For instance, if you see `Any<Collection where .Element == String>`, it's a small step to realize that you could also say `Any<Collection where .Index == Int>`. If you're always using `AnyCollection<String>`, on the other hand, you may never figure that out.

>> * In the `willSet` vs. `willset` thread, I proposed a rule that keywords which fit into a particular syntactic slot should be capitalized like normal members of that slot. For instance, if `dynamicType` is a pseudo-property, it should be capitalized like a property. Since `Any<>` fits in the syntactic slot of a type, it should be capitalized like a type.
> Any has some overlap with types, but it cannot be used everywhere a type can.

Are there places where you can use any type *except* an `Any<…>` type? I know there are places where you need to use (for instance) a class or a protocol, but in those cases Swift is rejecting a wide variety of unacceptable types, only one of which is `Any<…>`.

> This is precisely why it should be lowercase.  I don’t believe it falls under that exemption in your proposal.  I believe it’s a good exemption when the keyword is indistinguishable to users from a normal member.  I don’t believe it’s a good exemption when the behavior is “special” in some way.

The behavior of a keyword is always "special" in some way; if it weren't, it wouldn't be a keyword. `dynamicType` is special because it's available on all instances, even though `extension Any` is not valid. `willSet` is special (compared to accessors from user-provided property behaviors) because you don't need to enable some specific property behavior to get it. And `Any` is special because it's variadic and acts as a subtype of many unrelated types. But it still walks like a type and quacks like a type, and so we should still spell it like a type.

Brent Royal-Gordon

More information about the swift-evolution mailing list