Introduction of new keyword 'any' for protocol conforming arguments

I’m a native English speaker and I don’t really fully get the difference between any and some. Here i sort of do because I sort of understand the use cases.

The problem is there’s two type of people, language designers and app writers and language designers are more likely to know the exact definitions of words like any and some. Whereas the vast majority of people don’t really and just use them as a tool to convert meaning and as long as it works most of the time it doesn’t actually matter.

It would be nice if people designing the language acknowledged that Swift forums and Swift evolution is very niche.
I’m certainly grateful for the language that’s been created and the effort people have put into it but originally it was to make apps easier to write than objective-c (well at least that’s what Tim Cook said, which is what most of the world heard), however more lately it feels like the perfect language is trying to be created when really Swift is just a hammer to make apps, it’s better for it be easy to use than perfect. ie the hammer needs a rounded handle not a atomically perfect cuboid handle that hurts to hold.

2 Likes

All specialties have their jargon. In Swift, it's been necessary to distinguish between any and some since opaque result types were added for SwiftUI. It's just that until now, any wasn't a formal language term (keyword).

The TSPL has this to say about opaque types:

Unlike returning a value whose type is a protocol type, opaque types preserve type identity—the compiler has access to the type information, but clients of the module don’t.

This stands in contradistinction to existentials, variables of which can hold any conforming type at runtime. Thus, the compiler does not know the static type(s) which will be stored in the variable. any is just the syntax for writing any type conforming to in the source code.

1 Like

They're also not synonyms in the natural language sense.

However, I do think you have a point that the difference is subtle. And that the difference between the two terms as used in Swift, and the difference between the two terms as used in natural language, is non-obvious to many—perhaps most—people.

2 Likes

You mean it may not be obvious to some people, or to any people. :neutral_face:

12 Likes

As a plain datapoint, I can say that I won't update GRDB public apis, sample code in documentation snippets and guides, as well as demo apps, with any. Not until it becomes necessary (warnings or errors).

Those any, in function signatures, documentation, and sample code, are much to much "in the face" of the user, who may not even be aware of this new Swift 5.6 feature.

In the particular case of documentation, where you really not want the user to be distracted as you try to transfer pieces of knowledge, introducing any would be a big mistake (when I wear my hat of documentation writer).

Finally, having chosen (any P)? instead of any P? is, IMHO, a design mistake. The need for an optional existential is not less frequent than the need for an optional of another type, and those extra parenthesis are a chore to write, and a chore to read. I hope this decision is revisited: the plain any P? currently won't compile, so this form looks like it could find a purpose, even if it is less logical.

For example:

func f(_ dict: [String: (any MyProtocol)?]) { ... }

is more difficult to parse and understand, dare I say uglier, when compared to the two alternative forms:

func f(_ dict: [String: any MyProtocol?]) { ... }
func f(_ dict: [String: MyProtocol?]) { ... }

GRDB has plenty of such heterogeneous but convenient dictionaries, when it allows the user to match database columns (String) to database values (Int, String, Date, etc):

// A database row for testing purpose
let row: Row = ["id": 1, "name": "Arthur", "score": nil]

// A request on a unique index:
let player = try Player.fetchOne(db, key: ["email": "..."])

// etc.
4 Likes

I was and remain in agreement with this point; fortunately, it's a change that can be added later and the case for doing so can be enhanced with usage and feedback like this :slight_smile:

11 Likes

well, we had Any, which is syntactically a keyword and not a type. the potential for confusion comes from the way that any and some are planned to be contrasting modifiers in the same position, whereas so far, they have lived in different areas of the language and have not has as much opportunity to come into conflict.

Yeah, I was on the side of the any P? being parsed as any (P?) precisely because it was an invalid type, so we could relax this later if it turned out to be a usability issue (which appears to be the case :slightly_smiling_face:).

Thanks for your comments @gwendal.roue, @itaiferber. It's helped clarify my ideas. I feel I have to go "full Cassandra" though to try to avoid what could be a sticky situation later in the year and beyond (prophesied by this tweet)

The nub of SE-0335 is to deprecate unwitting use of existentials in passing arguments due to perceived performance concerns. I get that, but having moved this usage to one side by introducing a new any keyword what is the fate of the so-called "naked protocol" syntax for specifying a conforming argument? Deprecation would leave a bit of a crater in the language which I feel we should backfill with the tactical rewriting I propose to avoid a good deal of disruption. This also fits with my belief a developer shouldn't have to know generics to be able to use protocols. Otherwise, depending on the fixit I anticipate the uninitiated will simply slavishly add any locking the inefficient existential signature into their code.

I've said my piece and I'm not going to get agitated about this but I feel the introduction of this feature could be better staged or postponed until opportunities like "opening existentials" can be realised to reduce the disruption of this change to the broader Swift community.

2 Likes