[Pitch] Formalize ‘Swift language mode’ naming in tools and API

Hello Swift Community,

This proposal needs to be fleshed out in terms of exact details, but I wanted to pitch it to get feedback on the basic idea.

On the threshold of the community beginning migration to Swift 6 language mode, it seemed it might reduce confusion if the compiler and Swift PM APIs used the more unambiguous terminology. I did not find any previous proposals for this, my apologizes if this had already been pitched.

Thank you for your feedback!

James

Introduction

The term "Swift version” is ambiguous and a source of confusion because it can refer to the toolchain/compiler version or the language mode. This proposal is for the Swift compiler and Swift PM to formalize the term ‘language mode’ in tool options and APIs and deprecate using ‘swift version’ to refer to language mode.

Proposed Solution

The proposed solution is to use the 'language mode' terminology for the appropriate Swift compiler and Swift Package Manager options and API.

Swift compiler

Introduce a -swift-language-mode option that has the same behavior as the existing -swift-version option.

The -swift-version option would continue to work as it currently does, preserving backwards compatibility.

The -swift-language-mode option would be presented in help for the tool while -swift-version may possibly be suppressed.

The option could alternately be named -language-mode.

Swift Package Manager

The Swift Package Manager would have three main API changes limited to manifests >= 6.0:

1. A new Package init method that uses the language mode terminology.

Package(
    name: String,
    defaultLocalization: \[LanguageTag]? = nil.
    platforms: \[SupportedPlatform]? = nil,
    products: \[Product] = \[],
    dependencies: \[Package.Dependency] = \[],
    targets: \[Target] = \[],
    swiftLanguageModes: \[SwiftLanguageMode]? = nil,
    cLanguageStandard: CLanguageStandard? = nil,
    cxxLanguageStandard: CXXLanguageStandard? = nil
)

The parameter swiftLanguageVersions becomes swiftLanguageModes with the type being an optional array of SwiftLanguageMode values instead of SwiftVersion values.

The existing init methods would still exist but would be marked to prefer this new init method.

2. Add SwiftLanguageMode as typealias to SwiftVersion

Introduce SwiftLanguageMode as a typealias of SwiftVersion. (or the other way around if that makes for a smoother transition).

Update all references to SwiftVersion in the API to SwiftLanguageMode

3. Update API proposed in SE-0435: Swift Language Version Per Target:

public struct SwiftSetting \{
  // ... other settings
  
  @available(\_PackageDescription, introduced: 6.0)
  public static func swiftLanguageMode(
      \_ version: SwiftLanguageMode,
      \_ condition: BuildSettingCondition? = nil
 )

If both are added in the same release, the originally proposed API could potentially be added with the naming changes.

Source compatibility

This proposal is additive and should have no source compatibility issues.

Depending on how to availability is annotated, this proposal could introduce a warning that indicates the developer should move to the new Package init method.

ABI compatibility

I don’t believe this proposal would cause any ABI incompatibility but any incompatibilities should be surfaced and added here during the pitch process.

Alternatives considered

Continue to have an ambiguously named option/setting for language mode with the resulting ongoing confusion and explanations that the ambiguity causes.

13 Likes

An alternative would be to follow the SDK paradigm and have minimum / target versions. Like with SDKs, that leaves open the opportunity to have conditional code that uses newer compiler features if the compiler in use happens to have them.

This proposal is focused only on changing the name of an existing setting to make its meaning unambiguous.

The Swift 6.0 compiler/toolchain will support Swift 5 language mode and Swift 6 language mode (which enables strict concurrency checking and enforces it with errors).

The proposal aims to disambiguate the compiler/toolchain version from the version of Swift used as the language mode.

You can already use conditional compilation settings to get the results you describe.

For example:

#if compiler(>=5.5) will compile with any version of the Swift compiler/toolchain from 5.5 up.

#if swift(<6) will compile with any Swift language mode less than 6.

Right, but you get no help from the compiler if they're unreachable, because the compiler doesn't know enough about your constraints. Whereas if you tell it that the minimum target Swift version is 6, it can let you know that the first #if (above) is redundant, and the second is dead code.

Just saying the target language mode is 6 doesn't convey as strong a signal, because you might sometimes compile in mode 6, sometimes mode 5.

I think this is pretty esoteric in the grand scheme of things - I'd be surprised if there's a lot of need to dynamically switch language modes. I was just putting it out there.

1 Like

Okay, I understand better.

This proposal is definitely more basic than that.

When the LSG writes about the upcoming transition, the term that has been consistently used is 'language mode'. But the tools all refer to 'swift version'.

So a developer reads a post or migration guide talking about 'language mode' and then nothing in the tools or package APIs refer to a 'language mode'.

If having the compiler run using the semantics of a particular major version of the language is called 'language mode' then the name in the tooling should probably match. (Especially when the existing name is ambiguous and leads to confusion.)

But I don't think changing the names to use the currently used terminology would preclude what you are suggesting. It's just beyond the scope of this proposal.

5 Likes

I like this, I think "mode" much better captures what these settings are and decouples the nomenclature from the semver march that is attached to specific releases. It would be nice to standardize on the terminology in as many places as possible.

8 Likes

I really appreciate the desire for clarity; this is a great improvement.

"Mode" unfortunately itself requires qualification. "Standard" would work standalone, but has no precedent or advocate in Swift discussions. I can't think of a clear and common alternative, so... "swift-language-mode" it is?


Looking back from the future, one might consider this also in light of related terms and alternatives.

"Mode" is a term for any processing variant, so to be sensible one has to say "Swift language mode", not "Swift mode" or "language mode". "Mode" is also used for release/debug mode (but optimizations tend to be called levels).

The compiler has C/C++ language modes, which really distinguish languages. So it's a different distinction there, and means you'd always have to have per-language qualifier (C, C++, or Swift). In that vein, I can imagine needing to extend that c/c++ mode to distinguish later C++ or some enhance objective-C mode. (And a bare -language-mode compiler option might mislead people into trying to specify C/C++ modes there.)

The C++ community uses "standards" as the term for the version scope. It makes more sense to me to talk about the Swift 5 and 6 standard as the target/referent, and I can imagine implementations of the compiler, SPM, language server etc. that handle multiple standards. That could sensibly by a single-term option -standard, but -swift-language-standard would be clearer.

However, I don't see any such usage in the wild, and I do see some antipathy to the bureaucratic baggage in the notion of a standard.

3 Likes

Thank you for the feedback and for the exploration of other potential terms.

The pitch uses 'Swift language mode' mainly because that is how I have seen it described most often by the LSG in various written contexts, so it seemed to be the already established preferred naming for this option.

I agree with you that just -language-mode could be ambiguous, especially since it would be included in API for Swift PM which is able to have targets using languages other than Swift.

I am not well-versed in the intricacies of language standards, but my cursory understanding is that generally a standard would be a specification document from which somebody could build their own compiler that implements the standard.

I don't think Swift currently has a standard in that sense. So, I think it would probably be best to reserve the term 'standard'.

1 Like

The equivalent in the Rust world is “edition”, a term that I believe the Rust folks made up without particular precedent (though I didn’t research that deeply). I think “language mode” is fine, and an improvement over “version” (or “standard”, which got stretched with things like “gnu99”), but “edition” could probably be listed as a Considered Alternative.

7 Likes

Thank you for the feedback and I will definitely add "edition" to the considered alternatives. It is interesting that it seems Rust created a term without precedent. I think Swift has done the same with “language mode”.

Searching here in the forums, it does seem like "language mode" is a long-established term of art in the Swift community:
https://forums.swift.org/search?q=%22language%20mode%20%22
(A space added to end of search term to avoid finding 'language model')

This includes the posts in the last year from LSG members about Swift 6 language mode:

The earliest usage of the term I could find goes back to 2016 in a post describing the intent to allow for modules to use different versions of Swift:

From: End of source-breaking changes for Swift 3.

Overall, I am open to whatever name adds clarity and removes the ambiguity, but "language mode" appears to be the term that has been consistently used for a long while.

4 Likes

Thanks for starting this discussion! I personally prefer "language mode" instead of "language version" because the shortened "Swift 6 mode" is not ambiguous. As you've noticed, I've standardized "language mode" everywhere I've been discussing it.

I think -language-mode is better, no need to write swift in the name of a flag passed to a Swift compiler invocation!

14 Likes

You're welcome!

I did take my cue from how you and other LSG members have been using the term. And looking back it seems like its usage has grown over time.

Yes, I am guessing the current -swift-version only includes 'swift' because
-version is the standard option to print the version of a command line tool.

It would be nice though for the compiler flag and the naming in the Swift PM API to be the same. The proposed SE-0435 addition clearly applies to Swift since it is a SwiftSetting, so languageMode would be unambiguous there.

In the Package init though, it would probably be clearer as swiftLanguageModes since the parameter is alongside cLanguageStandard and cxxLanguageStandard.

(This proposal is essentially a bike-shedding perfect storm.)

5 Likes

The Language Steering Group discussed this pitch yesterday and we are broadly in favor of standardizing around the "language mode" terminology everywhere we can. One additional bit of surface area that we discussed was the current swift(...) and compiler(...) compile-time conditionals. The former currently corresponds to the language mode, while the latter corresponds to the compiler version. Without necessarily endorsing an exact spelling, the LSG believes that this should be included in a wholesale effort to align the terminology (e.g., languageMode(...), swiftLanguageMode(...) or similar).

The imminence of Swift 6 is of relevance here. While the LSG believes that clarifying this nomenclature is probably worth the churn, on balance, it is not necessarily clear that we would come to the same conclusion in a post-Swift-6 world. As such, we would be interested in seeing the details here ironed out and a proposal brought to review sooner rather than later.

7 Likes

“language mode” is how we always talked about -std in Clang. The user’s manual uses that and “standard mode” interchangeably, but the latter is an odd fit given that many of the language modes are things like gnu89 that do not correspond to a release of the standard.

5 Likes