Get Swift version information programmatically

(This is a follow-up on Get Swift language version programmatically which I started in “Using Swift”.)

I suggest to add some mechanism to get Swift language version information programmatically. For example:

print(#swiftVersionInformation)

producing

Apple Swift version 4.2-dev
// or
Apple Swift version 4.2-dev (LLVM 49e6f88643, Clang cf4f73cfc1, Swift 53be298f1f)

similar to what the swift REPL prints as welcome prompt (apparently in void Driver::printVersion).

Motivation:

I often switch between different Xcode apps (such as the current release and the latest beta). In addition I sometimes install additional toolchains, e.g. the “latest snapshot”, and it is not immediately obvious (to me) which Swift version such a toolchain corresponds to.

Therefore – only for information purposes! – some version string would be convenient to see what I am currently working with in my test programs.

The alternative would be a sequence of conditional compilation statements

#if swift(>=4.2)
print("Swift 4.2")
#elseif swift(>=4.1)
print("Swift 4.1")
#elseif swift(>=4.0)
...
#endif

which need the explicit knowledge of all available versions and must be maintained for new versions.

Please note:

This is not meant as a mechanism to check for Swift features or for conditional compilation depending on the compiler version, but solely for information purposes, when playing around with different Xcode apps or toolchains.

That also means that the exact format of that version string would not matter, it is not meant to be parsed to evaluated in any way.

1 Like

Would it make more sense to introduce a small type which will be shipped with the stdlib instead?

// Something like that
struct CompilerInformation {
   let version: (major: Int, minor: Int)
   // More interesting information
}
2 Likes

Yes, that is also a good suggestion. Actually the Swift compiler has something like that internally: class Version in swift/Basic/Version.h contains all the information (including the “effective version,” which would be interesting to know as well).

A possible disadvantage of such a type would be that it is more likely to be abused for conditional compilation than a free-form string.

Why is it abusage if it would be public anyway? At least I don‘t see it‘s disadvantages or anything harmful. You can still proof me wrong. ;)

There is already #if swift(>=...) which is the documented way to compile against different language versions. But don't get me wrong: I could well live with a struct CompilerInformation.

Let's see if there are more opinions, and in particular if such a feature is generally approved at all.

1 Like

+1
I guess something like this could be handy for performance testing, checking for differences between compiler versions, or in code that demonstrates compiler-version-specific-bugs.

We could of course just use swiftc --version for this, but having it included in and reported by the test/demonstration-program itself would be better IMO.

I would prefer something like the CompilerInformation type suggested by @DevAndArtist rather than a simple String, the type's description property could instead be the String (eg "Apple Swift version 4.2-dev (LLVM 49e6f88643, Clang cf4f73cfc1, Swift 53be298f1f)").

1 Like

If the intent is to turn this into a formal proposal, I think this motivation needs to be strengthened a bit. I understand the logic that "some version string would be convenient" — but how would it be use in practice to solve the problem? Are there alternatives beyond modifying the compiler that would be a good solution for the underlying problem you are trying to solve, or is this a solution that stands on its own?

In the formal proposal I suggest explaining this a bit more. Just a couple more sentences. Basically, one can reverse engineer the compiler version from the language compatibility modes supported from the compiler. In this case, #if swift is the language compatibility mode enabled, not the compiler version.

1 Like