The review of SE-0152 "Package Manager Tools Version" begins now and runs through February 13, 2017. The proposal is available here:
https://github.com/apple/swift-evolution/blob/master/proposals/0152-package-manager-tools-version.md
Hi Martin,
Thanks again for your feedback.
Regarding your first point, about whether this is necessary:
We could indeed choose to make the Swift 3 tools always interpret the manifest as Swift 3 and the Swift 4 tools always interpret it as Swift 4, and hope that no language changes affect code in manifests, but that's a pretty big risk -- either that manifests won't build, or that subtle incompatibilities between the modes could have unexpected side effects. Simple manifests might not be affected by language changes (though we really don't know that yet), but more complex manifests might be, which would still be a a problem.
If this was the main point of this proposal, I might agree that it isn't worth it for this single need, despite the risk. But there are two other things that we need this proposal for; the most important being allowing packages to avoid breaking dependency resolution from older versions of the Swift tools when they adopt new PackageDescription API (or any other Swift features, which might not be reflected in the Swift language compatibility version, e.g. if it's a feature added in a minor release). Since we want a Swift tools version defined for that need, we can get proper control "for free" over the language version used to parse the manifest.
Unfortunately, we can't just wait and see how much of a problem this is in practice and add it later if we need it; this mechanism needs to be understood by both a new breaking version of Swift (Swift 4) and the version prior (Swift 3.1) in order to have any effect, since the whole point is to keep the prior version from trying to use incompatible packages. Our window to get changes into 3.1 will close before too long, so it's now or never for this language transition.
Regarding your second point, about this being a comment:
That's a good point about the SGML DOCTYPE not actually being a comment; I can revise the proposal to fix that inaccuracy. I don't think that materially affects the tradeoffs between making this a comment vs. other approaches, though.
We discuss some alternatives to using a comment, and why we favor the comment, here:
https://github.com/apple/swift-evolution/blob/master/proposals/0152-package-manager-tools-version.md#store-the-swift-tools-version-in-a-separate-file
and here:
https://github.com/apple/swift-evolution/blob/master/proposals/0152-package-manager-tools-version.md#specify-the-swift-tools-version-with-a-more-swifty-syntax
There was a more detailed discussion of the tradeoffs in a version of the document we floated prior to formal review, before we had decided on the comment:
https://github.com/rballard/swift-evolution/blob/fd28010aaef077b9783d738eacd912915b55c67e/proposals/NNNN-package-manager-tools-version.md#how-the-swift-tools-version-is-specified
You suggest an alternative of grepping the Package.Swift for the string "swiftLanguageVersions". That approach seems like pretty unexpected, non-formal behavior for the tools. What happens if this string appears multiple times, which we expect will be the case once we have a proper build settings model and you can set swiftLanguageVersions on a per-module basis within the package? Would we parse (and be able to machine-edit) all syntaxes for setting the swiftLanguageVersions (initial initializer, mutating the property after Package() is initialized, expression to derive the RHS of the setter)? What would it mean if swiftLanguageVersions has multiple values, which is allowed? I don't see concrete benefits to this idea, and it adds new complexities and possibilities for error.
Note that the swiftLanguageVersions does _not_ actually have to be specified by the package otherwise. In the common case of a package whose language version is the same as its Swift tools version, no swiftLanguageVersions property need be specified -- and I expect that `swift package init` won't give you one by default.
We don't want to stipulate that the package manager needs to use the same mode for `Package.swift` as the rest of your sources, because we want you to be able to adopt new package manager API without having to simultaneously convert all your package's sources from Swift 3 to Swift 4. It's easier for our users if they can tackle language conversion when they're ready to, and not make it a prerequisite of using new SwiftPM features.
Ultimately, I think no one is thrilled with parsing the Swift tools version out of a comment, but the feedback we've received so far (off-list) has strongly favored that approach, and when we evaluated the tradeoffs vs. the other approaches we considered, it seemed the best.
Thanks,
- Rick
···
On Feb 8, 2017, at 12:17 AM, Martin Waitz via swift-build-dev <swift-build-dev@swift.org> wrote:
From the proposal:
Not changing this API would still leave the problem of figuring out which Swift language compatibility version to interpret the manifest in. It's possible that Package.swift manifests won't be significantly affected by Swift language changes in Swift 4, and could mostly work in either language compatibility mode without changes. However, we don't know whether that will be the case, and it would be a significant risk to assume that it will be.
I really assume that the simple `Package.swift` files will be able to be compiled in swift 3 and swift 4 modes.
Do we really need this proposal now?
If we really encounter problems, we can always add it later.
So what exactly is the risk?
When we want to introduce it already now, I’d like to revisit the way the tool version is specified.
Can we _please_ not use a comment?
Comments are comments and should have no influence on how to parse the file.
By the way, in XML/HTML, the DTD/Doctype is not specified in a comment, but in a processor instruction (`<!DOCTYPE html>` vs. `<!— comment —>`).
So the XML example would more closely resemble something like `#swift(3.0)` in Swift.
Maybe the package manager could just grep for the `swiftLanguageVersion` specification?
This has to be specified by the package anyway.
We could simply specify that the swift compiler always uses the same mode for `Package.swift` and the rest of the sources,
and that the package manager obtains this version from the manifest without using the full Swift compiler.
I.e. this line would be fixed to some special syntax (`^\s*swiftLanguageVersion\s*:\s*(\d+)\s*,\s*$` or something).
— Martin