[Review] SE-0181: Package Manager C/C++ Language Standard Support

Hello Swift community,

The review of SE-0181: Package Manager C/C++ Language Standard Support begins now and runs through July 14th, 2017.

The proposal is available here:

  swift-evolution/0181-package-manager-cpp-language-version.md at master · apple/swift-evolution · GitHub

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-build-dev and swift-evolution mailing lists at

  https://lists.swift.org/mailman/listinfo/swift-build-dev
  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:
Proposal link:

Reply text

Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at:

Thank you,
Daniel Dunbar (Review Manager)

[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0181-package-manager-cpp-language-version.md\]

I don't feel like I have the perspective for broad comments on the use cases for the proposal, but here are some low-level thoughts:

public enum CLanguageStandard {
    case c89
    case c90
    case iso9899_1990
    case iso9899_199409
    case gnu89
    case gnu90
    case c99
    case iso9899_1999
    case gnu99
    case c11
    case iso9899_2011
    case gnu11
}

I don't think it's worth having every name and every alias here. c89/gnu89, c99/gnu99, and c11/gnu11 covers all of the variants and is what's used most in practice anyway. (IIRC C89 and C90 have some tiny difference from the second standardization, but Clang ignores this difference anyway.)

public enum CXXLanguageStandard {
    case cxx98
    case cxx03
    case gnucxx98
    case gnucxx03
    case cxx11
    case gnucxx11
    case cxx14
    case gnucxx14
    case cxx1z
    case gnucxx1z
}

Similar thoughts here. I also wonder if "gnucxx98" is redundant, given that it's already in a containing enum called "CXXLanguageStandard" (or "CPPLanguageStandard", or even "CPlusPlusLanguageStandard", depending on how that discussion goes). "gnu98" seems sufficient.

I really don't like saying "cxx1z". Can we just say "cxx17" because it's really likely we'll get it this year?

If this were a longer-term issue (say, if there were references to "cxx2a") I'd ask what the plan is for aliases in the future. You'd want "cxx2a" and "cxx21" to eventually compare equal, right? But since this will get subsumed by build settings I think it's okay not to worry about that, or any custom standards a vendor or Clang experimenter might try to add.

Jordan

Hello Swift community,

The review of *SE-0181: Package Manager C/C++ Language Standard Support* begins
now and runs through *July 14th, 2017*.

The proposal is available here:

  GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/0181-package-manager-cpp-language-version.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-build-dev and swift-evolution mailing lists at

  https://lists.swift.org/mailman/listinfo/swift-build-dev
  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager. When replying, please try to keep the proposal link at the
top of the message:

Proposal link:

GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/0181-package-manager-cpp-language-version.md
Reply text

Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

   - What is your evaluation of the proposal?

As a temporary measure, acceptable; very much looking forward to true build
settings. I would tend to agree with original proposal authors that, since
this design is intended to be transitional, having these enum cases closely
mirror the underlying options 1:1 is the way to go.

   - Is the problem being addressed significant enough to warrant a
   change to Swift?

Yes.

   - Does this proposal fit well with the feel and direction of Swift?

It fits OK, with some nits:

* Since the corresponding Swift feature is specified by the label
`swiftLanguageVersion` and the proposed enum is named `CLanguageStandard`,
shouldn't the label be `cLanguageStandard` instead of `cStandard`?
* Since the underlying option is named "gnu++11", shouldn't the enum case
be `gnuxx11` and not `gnucxx11`?

   - If you have used other languages or libraries with a similar
   feature, how do you feel that this proposal compares to those?

This is the first package manager I've worked with that builds both another
language and C/C++.

   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

Some study, though not necessary as in-depth as it could be.

More information about the Swift evolution process is available at:

···

On Tue, Jul 11, 2017 at 12:54 PM, Daniel Dunbar via swift-evolution < swift-evolution@swift.org> wrote:

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,
Daniel Dunbar (Review Manager)

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0181-package-manager-cpp-language-version.md\]

I don't feel like I have the perspective for broad comments on the use cases for the proposal, but here are some low-level thoughts:

public enum CLanguageStandard {
    case c89
    case c90
    case iso9899_1990
    case iso9899_199409
    case gnu89
    case gnu90
    case c99
    case iso9899_1999
    case gnu99
    case c11
    case iso9899_2011
    case gnu11
}

I don't think it's worth having every name and every alias here. c89/gnu89, c99/gnu99, and c11/gnu11 covers all of the variants and is what's used most in practice anyway. (IIRC C89 and C90 have some tiny difference from the second standardization, but Clang ignores this difference anyway.)

I agree. It would be worth considering splitting this into two different dimensions: base language standard (90, 94, 99, 11) vs gnu/clang extensions (on/off). GNU extensions are generally compatible with non-extensions, so you may be able to get away with them always being enabled.

public enum CXXLanguageStandard {
    case cxx98
    case cxx03
    case gnucxx98
    case gnucxx03
    case cxx11
    case gnucxx11
    case cxx14
    case gnucxx14
    case cxx1z
    case gnucxx1z
}

Similar thoughts here. I also wonder if "gnucxx98" is redundant, given that it's already in a containing enum called "CXXLanguageStandard" (or "CPPLanguageStandard", or even "CPlusPlusLanguageStandard", depending on how that discussion goes). "gnu98" seems sufficient.

Likewise with the above, this could be much simpler.

-Chris

···

On Jul 12, 2017, at 3:03 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

A couple more points I skipped earlier...

[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0181-package-manager-cpp-language-version.md\]

I don't feel like I have the perspective for broad comments on the use cases for the proposal, but here are some low-level thoughts:

public enum CLanguageStandard {
    case c89
    case c90
    case iso9899_1990
    case iso9899_199409
    case gnu89
    case gnu90
    case c99
    case iso9899_1999
    case gnu99
    case c11
    case iso9899_2011
    case gnu11
}

I don't think it's worth having every name and every alias here. c89/gnu89, c99/gnu99, and c11/gnu11 covers all of the variants and is what's used most in practice anyway. (IIRC C89 and C90 have some tiny difference from the second standardization, but Clang ignores this difference anyway.)

public enum CXXLanguageStandard {
    case cxx98
    case cxx03
    case gnucxx98
    case gnucxx03
    case cxx11
    case gnucxx11
    case cxx14
    case gnucxx14
    case cxx1z
    case gnucxx1z
}

Similar thoughts here. I also wonder if "gnucxx98" is redundant, given that it's already in a containing enum called "CXXLanguageStandard" (or "CPPLanguageStandard", or even "CPlusPlusLanguageStandard", depending on how that discussion goes). "gnu98" seems sufficient.

I really don't like saying "cxx1z". Can we just say "cxx17" because it's really likely we'll get it this year?

I don't want us to be in the position of making these kinds of decision. I want the one source of truth to rest with the compiler, and we will just reflect what the tools support. So, if you believe this is the right answer I think Clang should accept c++17, and then we will follow along (and deprecate the old API).

If this were a longer-term issue (say, if there were references to "cxx2a") I'd ask what the plan is for aliases in the future. You'd want "cxx2a" and "cxx21" to eventually compare equal, right? But since this will get subsumed by build settings I think it's okay not to worry about that, or any custom standards a vendor or Clang experimenter might try to add.

I don't know that I would expect cxx2a and cxx21 to compare equal -- they would be distinct from the perspective of changing what is passed to the compiler. I would imagine if we wanted to support a more semantic notion like this, we would expose a custom API for it.

- Daniel

···

On Jul 12, 2017, at 3:03 PM, Jordan Rose <jordan_rose@apple.com> wrote:

Jordan

Combo reply...

[Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0181-package-manager-cpp-language-version.md\]

I don't feel like I have the perspective for broad comments on the use cases for the proposal, but here are some low-level thoughts:

public enum CLanguageStandard {
    case c89
    case c90
    case iso9899_1990
    case iso9899_199409
    case gnu89
    case gnu90
    case c99
    case iso9899_1999
    case gnu99
    case c11
    case iso9899_2011
    case gnu11
}

I don't think it's worth having every name and every alias here. c89/gnu89, c99/gnu99, and c11/gnu11 covers all of the variants and is what's used most in practice anyway. (IIRC C89 and C90 have some tiny difference from the second standardization, but Clang ignores this difference anyway.)

I agree. It would be worth considering splitting this into two different dimensions: base language standard (90, 94, 99, 11) vs gnu/clang extensions (on/off). GNU extensions are generally compatible with non-extensions, so you may be able to get away with them always being enabled.

I initially thought the same thing (we should avoid the aliases and simplify as much as possible).

However, I also have a guiding philosophy that "eventually" it should be possible to target everything the tools can do with SwiftPM (consider the use case of a compiler engineer wanting to test the behavior of iso9899:1999 mode, for whatever obnoxious reason). After thinking about it more I felt that supporting all of the non-deprecated GCC/Clang modes had little downsides, and was easier to justify in terms of this philosophy. The other alternative would be to support a limited set of modes and then an "other(String)" case, but I prefer this solution to that.

Given that we anticipate replacing this case with a more comprehensive "build setting" feature at some point, I would rather KISS which in this case means making the enum definitions 1:1 with the GCC/Clang ones.

Completely disregarding the GNU/Clang extension modes (and forcing it on where supported) and then dropping down to the minimal "useful" set (C{89,9911}, C++{98,03,11,14,1z}) would also be fine with me, but it is marginally more complicated to implement/explain and I'm not sure worth it.

public enum CXXLanguageStandard {
    case cxx98
    case cxx03
    case gnucxx98
    case gnucxx03
    case cxx11
    case gnucxx11
    case cxx14
    case gnucxx14
    case cxx1z
    case gnucxx1z
}

Similar thoughts here. I also wonder if "gnucxx98" is redundant, given that it's already in a containing enum called "CXXLanguageStandard" (or "CPPLanguageStandard", or even "CPlusPlusLanguageStandard", depending on how that discussion goes). "gnu98" seems sufficient.

It is redundant, but it also has a very clear mapping to the GCC/Clang values. What would you call the enum values to take advantage of this duplication?

- Daniel

···

On Jul 12, 2017, at 3:58 PM, Chris Lattner via swift-build-dev <swift-build-dev@swift.org> wrote:

On Jul 12, 2017, at 3:03 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Likewise with the above, this could be much simpler.

-Chris

_______________________________________________
swift-build-dev mailing list
swift-build-dev@swift.org <mailto:swift-build-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-build-dev

Hi,

···

On 13. Jul 2017, at 00:58, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

I agree. It would be worth considering splitting this into two different dimensions: base language standard (90, 94, 99, 11) vs gnu/clang extensions (on/off). GNU extensions are generally compatible with non-extensions, so you may be able to get away with them always being enabled.

On the second point, I really want to know when I’m (usually accidentally) using any (GNU or otherwise) extensions, so I would strongly prefer them not being forcibly enabled.

  Daniel.

FWIW, you are always using GNU mode in Swift, and we don't provide a direct way to control that. (But clearly that matters less for header files.)

Jordan

···

On Jul 13, 2017, at 02:12, Daniel Vollmer <lists@maven.de> wrote:

Hi,

On 13. Jul 2017, at 00:58, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

I agree. It would be worth considering splitting this into two different dimensions: base language standard (90, 94, 99, 11) vs gnu/clang extensions (on/off). GNU extensions are generally compatible with non-extensions, so you may be able to get away with them always being enabled.

On the second point, I really want to know when I’m (usually accidentally) using any (GNU or otherwise) extensions, so I would strongly prefer them not being forcibly enabled.-