Is it possible to rename keywords like `associatedtype` (in future Swift versions)?

I'm reading the Swift book, and was mildly surprised by the associatedtype keyword. I thought aliastype would have been a better name. It's shorter, and would compliment typealias.

I'm not proposing anything here, but wondered if changes like this are still possible even? How high would the bar be for a breaking change like that?

My initial reaction was the same, but I have gotten used to it now. :slight_smile:

As for the aliastype, it sounds almost the same as the typealias and thus would be confusing.

Although a long keyword, associatedtype does the job nicely as it is derived from the phrase associated type, which sounds natural. I read it as the actual type that is substituted.

5 Likes

An associated type isn't necessarily an alias. For example, SwiftUI's UIViewRepresentable protocol has an associated type named Coordinator. You can supply the Coordinator type like this:

struct MyRep: UIViewRepresentable {
  class Coordinator {
    ...
  }

  func makeCoordinator() -> Coordinator {
    ...
  }

  ...
}

Here, MyRep.Coordinator is the only name for the type it names; it is not an alias for some other, ‘true’ name.

15 Likes

As for the aliastype, it sounds almost the same as the typealias and thus would be confusing.

@ibex10 - They are meant to sound similar. They are literally the inverse of one another. Sorry. I didn't explain the idea very clearly. I was only interested in how open Swift is to changing something like this, if the community wanted to change it. I wasn't proposing this change in particular.

An associated type isn't necessarily an alias.

@mayoff - I know, but (as in English) the term type alias (necessarily) describes an alias (for a type), while the term alias type describes a type (for an alias).

If this idea were adopted, the nomenclature would be updated to refer to associated types as alias types. I think that'd be far more intuitive. We'd be consistently using the term alias (for a name associated with a type), rather than using it in one keyword, then overloading the term associated, which is already used for associated values in enums, which is a distinct concept (IIUC), in another keyword.

Still, I just wanted to know how open the community and maintainers are to making these kinds of breaking changes in future versions of Swift. I'm not making a proposal :grinning:

FWIW, “Associated type” is a well-known term of art, which I believe was introduced in https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/assoc.pdf.

9 Likes

I can’t speak for the core team, but my understanding of the situation is:

The general rule is “no source breaks”. Swift 6 is in the unusual position of being forced to accept some source breakage in order to meet the language’s core goals (safety, in this case for Swift Concurrency), which opens the door to potentially accepting a few more since people will already be dealing with it.

The bar for these is still quite high; fixing serious problems in practice, not just aesthetic or nice-to-have stuff. If you wanted a change like this, I would expect step one to be demonstrating that the problem being solved is one that meets that bar.

Doug goes into more detail here: Design Priorities for the Swift 6 Language Mode

My personal feeling on it is that this change would actually make the language slightly worse, since it would be difficult to remember which goes where with them so similar. But I don’t tend to have strong opinions about surface syntax, so if folks disagree with me I’m not inclined to argue.

9 Likes

My one and only gripe with associatedtype is that I instinctively want to write it camel-cased (associatedType).

We could definitely improve the diagnostics when that happens:

Welcome to Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100).
Type :help for assistance.
  1> protocol A { 
  2.     associatedType Foo 
  3. }
expression failed to parse:
error: error while processing module import: error: repl.swift:2:5: error: expected 'func' keyword in instance method declaration
    associatedType Foo
    ^
    func 

error: repl.swift:2:20: error: found an unexpected second identifier in function declaration; is there an accidental break?
    associatedType Foo
                   ^

repl.swift:2:20: note: join the identifiers together
    associatedType Foo
    ~~~~~~~~~~~~~~~^~~
    associatedTypeFoo

error: repl.swift:2:23: error: expected '(' in argument list of function declaration
    associatedType Foo
                      ^

(GitHub issue)

9 Likes

@David_Smith - Thanks for the link, and your feedback. I'm still new to Swift, so am not really knowledgable enough to argue the case either way. It was just an example really (though I appreciated your thoughts, still).

1 Like

No problem :) I'm glad you're interested in contributing!

1 Like

I didn't know that. It makes a lot more sense if there's a precedent for the term.

I can’t speak definitively for the whole Language Steering Group, but I think this would be a tough sell.

Let’s start with some historical background. Fun fact: The keyword for associatedtype used to be…typealias! From Swift 1.0 to Swift 2.1, the typealias keyword meant one thing in a protocol declaration and another thing anywhere else.

One of the first Evolution proposals, SE-0011, separated associatedtype from typealias because even though the two concepts were kind of related, they were distinct enough that sharing a keyword was felt to be too confusing. Your pitch wouldn’t completely reverse that proposal, since aliastype and typealias would be different keywords, but it sort of goes against the spirit of it by making the concepts much easier to confuse.

Even if we did decide that your keyword was better, though, though, I think your proposal would still be difficult to accept. Completely renaming a keyword is source-breaking and certainly not something we’d consider. Deprecating the old keyword and introducing a new one is at least not out of the question—which is why we were willing to do it in SE-0011—but we’re usually reluctant to do that kind of thing because it has a lot of serious costs. For instance:

  • People have already learned the associatedtype keyword. They will have to learn something new and learn that it’s equivalent to associatedtype.

  • There’s tons of documentation, books, blog posts, StackOverflow answers, videos, etc. that use the associatedtype keyword. These would all have to be updated, and in practice, many of them will never be.

  • Projects which adopted the new keyword would not be buildable with tools from before this change. That would be especially bad for the package ecosystem, because adopting the new keyword would require a major version number bump, but would have no tangible benefit for dependents of the package.

The developer community understandably has a limited tolerance for this kind of “code churn”, so we try to avoid it unless the benefits are clearly worth it. Requiring any before existential types, for instance, has all of the above disadvantages, but we think it’s worth it to clarify a part of the type system that is frequently misunderstood in subtle and frustrating ways. Even SE-0011 was justified as not simply changing a keyword, but separating two concepts whose shared keyword made them easy to confuse. Merely renaming a mediocre-but-serviceable keyword probably doesn’t meet that bar.

Finally, it’s important to understand that our appetite for code churn has dropped over the years as Swift has become more popular and stable. We accepted SE-0011 back when we were still breaking things pretty often (Swift 3 renamed most Objective-C methods!), but I’m not sure we would if it were proposed today.

In short, I think this ship has probably sailed. Sorry.

15 Likes

Cheers @beccadax. I appreciate the time you've taken to explain the situation for me. Thank you. That's exactly what I was trying to understand.

This all makes perfect sense, and seems like the right approach to Swift evolution at this stage.

Thanks again.

3 Likes