[Proposal] Swift 2.2: #if swift language version

That's not how I read it. The stable ABI point says (emphasis mine):

Stabilize the binary interface (ABI) to guarantee a level of binary compatibility moving forward. This involves finalizing runtime data structures, name mangling, calling conventions, and so on, as well as finalizing some of the details of the language itself that have an impact on its ABI. **Stabilizing the ABI also extends to the Standard Library, its data types, and core algorithms.** Successful ABI stabilization means that applications and libraries compiled with future versions of Swift can interact at a binary level with applications and libraries compiled with Swift 3.0, even if the source language changes.

If Swift 3 succeeds with this goal, there can be new interfaces in the standard library, but existing interfaces will be final.

Basically correct, though changes are possible to existing interfaces after a long period of deprecation.

My experience with other languages is that even when it's possible to determine if the compiler/library supports some feature, unless you're a Boost maintainer, people tend to target one version of the language anyway, either the older one using a workaround portable to the newer version, or the new version without regards to people stuck behind.

The one notable exception I can think of is Python 2 vs Python 3, but that's because the "ABI" underwent very important changes.

That's why I'm asking what it would be used for.

@felix Swift 3 will stabilize ABI (binary level compatibility) but not the standard library interfaces (cf. GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. > Out of Scope > Full source compatibility).

Even is they are stabilized in the future, there can still be some API added in future Swift versions.

My understanding is that Swift 3 will stabilize the ABI and the standard library interfaces. Given that, I'm not sure what you'd use it for either.

What's the intended most common use case for this? The one that I can think of that will show up very often is "declare this function only if Swift version is >= X because it relies on some new feature"
In that case, would it make sense for consistency to also be able to mark a function (or type) as "only available on Swift >= X", like you do with ios releases? (ie @available(swift, 2.2))

>
>>
>>
>>>
>>>
>>> Sounds like it could be super useful for libraries!
>>>
>>> How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?
>>
>> I agree with Radek.
>>
>> The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.
>>
>> However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.
>
> This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.
>
> - Doug
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

David
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Javier Soto _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

--
Cordialement,
Ludovic Landry

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

-Dave

···

On Dec 19, 2015, at 1:26 PM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

Le 19 déc. 2015 à 15:52:08, Ludovic LANDRY <landryludovic@gmail.com <mailto:landryludovic@gmail.com>> a écrit :
On Sat, Dec 19, 2015 at 12:26 PM, Félix Cloutier <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Le 19 déc. 2015 à 14:26:24, Javier Soto via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
On Sat, Dec 19, 2015 at 1:28 AM David Farler via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

My understanding is that Swift 3 will stabilize the ABI and the standard library interfaces. Given that, I'm not sure what you'd use it for either.

···

Le 19 déc. 2015 à 14:26:24, Javier Soto via swift-evolution <swift-evolution@swift.org> a écrit :

What's the intended most common use case for this? The one that I can think of that will show up very often is "declare this function only if Swift version is >= X because it relies on some new feature"
In that case, would it make sense for consistency to also be able to mark a function (or type) as "only available on Swift >= X", like you do with ios releases? (ie @available(swift, 2.2))
On Sat, Dec 19, 2015 at 1:28 AM David Farler via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

> On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
>>
>> On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>>
>>> On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>
>>> Sounds like it could be super useful for libraries!
>>>
>>> How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?
>>
>> I agree with Radek.
>>
>> The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.
>>
>> However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.
>
> This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.
>
> - Doug
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

David
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Javier Soto _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

That's not how I read it. The stable ABI point says (emphasis mine):

Stabilize the binary interface (ABI) to guarantee a level of binary compatibility moving forward. This involves finalizing runtime data structures, name mangling, calling conventions, and so on, as well as finalizing some of the details of the language itself that have an impact on its ABI. **Stabilizing the ABI also extends to the Standard Library, its data types, and core algorithms.** Successful ABI stabilization means that applications and libraries compiled with future versions of Swift can interact at a binary level with applications and libraries compiled with Swift 3.0, even if the source language changes.

If Swift 3 succeeds with this goal, there can be new interfaces in the standard library, but existing interfaces will be final.

My experience with other languages is that even when it's possible to determine if the compiler/library supports some feature, unless you're a Boost maintainer, people tend to target one version of the language anyway, either the older one using a workaround portable to the newer version, or the new version without regards to people stuck behind.

The one notable exception I can think of is Python 2 vs Python 3, but that's because the "ABI" underwent very important changes.

That's why I'm asking what it would be used for.

···

Le 19 déc. 2015 à 15:52:08, Ludovic LANDRY <landryludovic@gmail.com> a écrit :

@felix Swift 3 will stabilize ABI (binary level compatibility) but not the standard library interfaces (cf. GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language. > Out of Scope > Full source compatibility).

Even is they are stabilized in the future, there can still be some API added in future Swift versions.

On Sat, Dec 19, 2015 at 12:26 PM, Félix Cloutier <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
My understanding is that Swift 3 will stabilize the ABI and the standard library interfaces. Given that, I'm not sure what you'd use it for either.

Le 19 déc. 2015 à 14:26:24, Javier Soto via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

What's the intended most common use case for this? The one that I can think of that will show up very often is "declare this function only if Swift version is >= X because it relies on some new feature"
In that case, would it make sense for consistency to also be able to mark a function (or type) as "only available on Swift >= X", like you do with ios releases? (ie @available(swift, 2.2))
On Sat, Dec 19, 2015 at 1:28 AM David Farler via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

> On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
>>
>> On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>>
>>> On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>
>>> Sounds like it could be super useful for libraries!
>>>
>>> How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?
>>
>> I agree with Radek.
>>
>> The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.
>>
>> However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.
>
> This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.
>
> - Doug
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

David
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
--
Javier Soto _______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

--
Cordialement,
Ludovic Landry

Yes, I see your point in that. It might be worth revisiting that for all of the build configs in the future.

David

···

On Dec 19, 2015, at 15:51, Félix Cloutier <felixcca@yahoo.ca> wrote:

It's not surprising that what's inside an if swift block isn't compiled, but since it doesn't, it might be surprising that what is inside an if DEBUG block is compiled, no?

Le 19 déc. 2015 à 17:58:35, David Farler <dfarler@apple.com> a écrit :

I don't know if I would say it violates the principle of least surprise because it wouldn't actually be a surprise in this case, since it's the whole reason you would choose to use `#if swift` – to ignore irrelevant syntax errors.

The difference is also smaller than you might think. The #else branches in the other build configurations parse because presumably the language's syntax wouldn't change between operating systems or architectures, however they never go through type checking or semantic analysis. For example:

cat -n test.swift

1 if os(iOS)
2 print("Hello")
3 #else
4 print("Hello")
5 #endif

Compiling for OS X, both branches are valid Swift and would actually type check fine, but:

xcrun -sdk macosx swiftc -dump-ast test.swift

(source_file
(top_level_code_decl
  (brace_stmt
    (#if_stmt
      (#if:
        (call_expr type='<null>'

...snip -- all null types up to here.

      #else
        (elements
          (top_level_code_decl
            (brace_stmt
              (call_expr type='()'

...snip -- all typed up to here.

So, maybe we should revisit the other build configurations in the future, that it's maybe not worth it to even parse any inactive branches, but I don't think the difference is so strong that we shouldn't reuse the if syntax for this now.

David

On Dec 19, 2015, at 2:17 PM, Félix Cloutier <felixcca@yahoo.ca> wrote:

I don't really like how different this makes "if swift" from "if <anything else>". To me, that would be a violation of the principle of least astonishment.

Le 19 déc. 2015 à 17:08:13, David Farler via swift-evolution <swift-evolution@swift.org> a écrit :

On Dec 19, 2015, at 13:48, Michel Fortin <michel.fortin@michelf.ca> wrote:

Le 18 déc. 2015 à 15:22, David Farler via swift-evolution <swift-evolution@swift.org> a écrit :

if swift("2.2")
print("Hello")
#else
this code will not parse or emit diagnostics
#endif

This is a change from how the if directive currently works. Currently, it's a syntax error to write this:

if DEBUG
@abaraka func test() {}
#endif

even if DEBUG is false because the content is parsed regardless and @abaraka is not a valid attribute. The syntax inside the if/#endif must be valid for the parser.

So this proposal implies a change in how if is parsed. Should it works like the C preprocessor?

--
Michel Fortin
michel.fortin@michel

Yes, that's right, it is a change but only for this new directive because one of its uses is to control exposure to syntax or API changes. Other build configurations such as 'os' and 'arch' will be unaffected.

I myself wouldn't want build configs to act like the C preprocessor, although that kind of change is probably out of this proposal's scope anyway, IMO.

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

Are you in favor of the original syntax?

David

···

On Dec 19, 2015, at 22:01, Jordan Rose <jordan_rose@apple.com> wrote:

On Dec 19, 2015, at 1:28 , David Farler via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

Sounds like it could be super useful for libraries!

How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?

I agree with Radek.

The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.

However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.

This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.

   - Doug

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

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

I don't like either of these. I especially don't like option 2 because it makes "swift" something magic while user flags are still limited to booleans, and I don't think we're likely to change user flags any time soon. But I don't like option 1 either. We didn't do it for "if #available(…)", and I don't think we need to do it here either.

Jordan

What about the following syntax?
if Swift.sinceVersion( 2, minor: 2 )
or even better:
if Swift.isFeatureAvailable( "foo" )
The look&feel is standard Swift. Just at compile time. In both cases optional parameter values are possible.

- Dirk

···

On 20 Dec 2015, at 07:01, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 19, 2015, at 1:28 , David Farler via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

Sounds like it could be super useful for libraries!

How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?

I agree with Radek.

The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.

However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.

This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.

   - Doug

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

I don't like either of these. I especially don't like option 2 because it makes "swift" something magic while user flags are still limited to booleans, and I don't think we're likely to change user flags any time soon. But I don't like option 1 either. We didn't do it for "if #available(…)", and I don't think we need to do it here either.

Jordan

My experience with other languages is that [...] unless you're a Boost maintainer, people tend to target one version of the language anyway, either the older one using a workaround portable to the newer version, or the new version without regards to people stuck behind.

That's not how it works with Apple. Every summer we get a new beta version of Xcode with a new version of Swift, which we should use for all new developments (because it'll become the shipping version in the fall), but we have to use an older one for App Store-ready products if we want to be able to submit updates. So libraries do often support several versions of the language.

Just look the libraries that still support dual ARC/non-ARC modes, which is something that's not necessary at all.

A.

I think we should be moving towards feature detection over swift version detection

···

Sent from my iPhone

On 20 Dec 2015, at 06:32, Dirk Schreib via swift-evolution <swift-evolution@swift.org> wrote:

On 20 Dec 2015, at 07:01, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 19, 2015, at 1:28 , David Farler via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 3:34 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:29 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:25 PM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

Sounds like it could be super useful for libraries!

How about we drop the quote marks, though? If we have `os(iOS)` and `#available(iOS 9, *)` (in other context), why not `swift(2.2)`?

I agree with Radek.

The argument to use a string is if we wanted to support subversions, e.g. like “if swift(2.2.1)”. This requires the parameter to be a string, because 2.2.1 isn’t a valid floating point literal - the lexer will be displeased.

However, I don’t think we *want* the feature to be able to do that. The most important use case for this feature is to handle syntactic differences across swift versions, and we don’t want those in sub-versions. Given that, it seems better to keep the syntax clean and simple.

This feature LGTM, and I also prefer that we drop the quotes. Two levels of version number should be sufficient.

  - Doug

Chris brought something up that a few of us had discussed in the past: the ambiguity of what the operation does. It's implicitly "current version >= specified version", but I wonder how many people will want to compare otherwise or will assume the comparison is '=='.

We can fix this in two ways:

Option 1: if swift(<x.y)

or

Option 2: if swift > x.y

I thought I preferred Option 1 but I think Option 2 reads more how you would expect and somewhat reflects the regular syntax of the language, FWIW. I sketched out both implementations and they're about the same in complexity, so I would suggest Option 2, unless it's a strong goal to keep special sauce in build configurations as "function calls".

Maybe not all of the comparison operators are necessary, but in general this gives some flexibility to arrange checks (newer code at the top or at the bottom) and actually describes what comparison is happening.

I don't like either of these. I especially don't like option 2 because it makes "swift" something magic while user flags are still limited to booleans, and I don't think we're likely to change user flags any time soon. But I don't like option 1 either. We didn't do it for "if #available(…)", and I don't think we need to do it here either.

Jordan

What about the following syntax?
if Swift.sinceVersion( 2, minor: 2 )
or even better:
if Swift.isFeatureAvailable( "foo" )
The look&feel is standard Swift. Just at compile time. In both cases optional parameter values are possible.

- Dirk

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

But the thing is, right now it’s not just new features that show up in new releases. We also have breaking syntax changes.

Feature detection make more sense in the future (perhaps one day we could have an “unstable” Swift branch with experimental features), but right now version detection makes more sense.

— Radek

···

On 20 Dec 2015, at 20:28, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

I think we should be moving towards feature detection over swift version detection

I’m a huge fan of feature detection (__has_feature and __has_include in Clang are some of my contributions), but I don’t think that makes sense here. We want swift to have a linear and consistent version numbering scheme. This means that "Swift 2.2” and “Swift 3.0” should mean something across all the potential implementations, at least in terms of the compiler and standard library interfaces. I do agree that something like “has package” could make sense.

Someone upthread asked for a specific use-case, here it is:

- At some point in time, Swift 3 will be widely available to developers in Beta form, but not yet finalized.
- At this point Swift 2.2 will be finalized and lots of code will be building against Swift 2.2.
- Swift 3 will be source incompatible with Swift 2.2.

It would be unfortunate if the huge number of frequently used packages (e.g. AlamoFire as one random example) would have to make a choice between the two, or fork their own development. Having if checks against versions numbers for the months where Swift 3 is in development - but not yet finalized - can ease pain for teams trying to maintain their code. Sometime after Swift 3 is out the door, they can then remove the old swift 2.2 support code and move on with life.

-Chris

···

On Dec 20, 2015, at 11:28 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

I think we should be moving towards feature detection over swift version detection

While that is true, I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid. I wonder about the wisdom in designing part of the language to handle the fact they are not finished designing the language.

Perhaps as an compromise, they could treat different versions of swift as features in and of themselves?

- Rod

···

On 21 Dec 2015, at 7:33 AM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

But the thing is, right now it’s not just new features that show up in new releases. We also have breaking syntax changes.

Feature detection make more sense in the future (perhaps one day we could have an “unstable” Swift branch with experimental features), but right now version detection makes more sense.

— Radek

On 20 Dec 2015, at 20:28, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

I think we should be moving towards feature detection over swift version detection

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

Also in future versions features may go away meaning older libraries may assume that greater than swift 2 is all that is needed to imply compatibility. Also libraries may be written against features they may not know which version of swift it will get into. Additionally certain features aren't available across platforms so how do you know what swift 2 means across platforms ?

Swift version conditionals are a useful fallback but we should also try and make feature conditionals a first class citizen too.

I love the @supports syntax in CSS, if we could do that then that would be awesome :) it's a great way of handling implementations across platforms

···

Sent from my iPhone

On 20 Dec 2015, at 21:00, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org> wrote:

I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid.

Are you implying that Swift 4 will have zero new features? Nothing that libraries will want to use conditionally when available?

A.

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

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Then at least everyone can opt-in to using it for availability checks. This should of course tie into the Swift Package Manager and use proper semver syntax (might as well use node’s example: https://docs.npmjs.com/misc/semver\).

Another solution would be to simply factor out the code into separate files and add each to the appropriate build configuration. Then nothing new needs to be added.

-David

···

On Dec 20, 2015, at 2:01 PM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

Also in future versions features may go away meaning older libraries may assume that greater than swift 2 is all that is needed to imply compatibility. Also libraries may be written against features they may not know which version of swift it will get into. Additionally certain features aren't available across platforms so how do you know what swift 2 means across platforms ?

Swift version conditionals are a useful fallback but we should also try and make feature conditionals a first class citizen too.

I love the @supports syntax in CSS, if we could do that then that would be awesome :) it's a great way of handling implementations across platforms

Sent from my iPhone

On 20 Dec 2015, at 21:00, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org> wrote:

I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid.

Are you implying that Swift 4 will have zero new features? Nothing that libraries will want to use conditionally when available?

A.

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

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

I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid.

Are you implying that Swift 4 will have zero new features? Nothing that libraries will want to use conditionally when available?

A.

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Big +1.

I've asked specifically to get some kind of conditional compilation on corelibs-foundation <https://lists.swift.org/pipermail/swift-corelibs-dev/Week-of-Mon-20151228/000287.html&gt; being used. corelibs-founcation is currently incompatible with Darwin Foundation, and so it is impractical to make a single codebase build for both.

But building the same application against both Foundations and spotting differences is one of the important ways we're going to spot bugs.

So I think the code quality of Foundation ultimately hinges on getting some feature like this in the language.

We already have @- and #-prefixed availability-like constructs, so I would prefer something more specific to the task – I wouldn't want to dilute the meaning of a package name argument by supplying it with the magic package "swift", for example. Changes to the language can be highly disruptive to all Swift code, so that's why I think it warrants its own build configuration.

David

···

On Dec 20, 2015, at 10:45 PM, David Owens II via swift-evolution <swift-evolution@swift.org> wrote:

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Then at least everyone can opt-in to using it for availability checks. This should of course tie into the Swift Package Manager and use proper semver syntax (might as well use node’s example: https://docs.npmjs.com/misc/semver\).

Another solution would be to simply factor out the code into separate files and add each to the appropriate build configuration. Then nothing new needs to be added.

-David

On Dec 20, 2015, at 2:01 PM, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Also in future versions features may go away meaning older libraries may assume that greater than swift 2 is all that is needed to imply compatibility. Also libraries may be written against features they may not know which version of swift it will get into. Additionally certain features aren't available across platforms so how do you know what swift 2 means across platforms ?

Swift version conditionals are a useful fallback but we should also try and make feature conditionals a first class citizen too.

I love the @supports syntax in CSS, if we could do that then that would be awesome :) it's a great way of handling implementations across platforms

Sent from my iPhone

On 20 Dec 2015, at 21:00, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid.

Are you implying that Swift 4 will have zero new features? Nothing that libraries will want to use conditionally when available?

A.

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

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

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

+1 from me as well, supporting conditional compilation when the two versions of foundation differ and may differ for the foreseeable future seems a must on this end.

···

Sent from my iPhone

On 3 Jan 2016, at 10:12, Drew Crawford via swift-evolution <swift-evolution@swift.org> wrote:

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Big +1.

I've asked specifically to get some kind of conditional compilation on corelibs-foundation being used. corelibs-founcation is currently incompatible with Darwin Foundation, and so it is impractical to make a single codebase build for both.

But building the same application against both Foundations and spotting differences is one of the important ways we're going to spot bugs.

So I think the code quality of Foundation ultimately hinges on getting some feature like this in the language.

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

The @available() and if #available constructs are not sufficient as they fall under the same limitations that your proposal addresses: they require that the non-valid branch not be parsed. For example, an API that has changes with a new language feature, such as variadic generic arguments, would not be able to be defined.

If we look at the grammar, I don’t see why the grammar for “availability-argument” couldn’t look like this:

    availability-argument: (platform-name | language-name | package-name) version.
GRAMMAR OF AN AVAILABILITY CONDITION

<>availability-condition → #available­(­availability-arguments <The Swift Programming Language: Redirect
<>availability-arguments → availability-argument <The Swift Programming Language: Redirect availability-argument <The Swift Programming Language: Redirect <The Swift Programming Language: Redirect
<>availability-argument → platform-name <The Swift Programming Language: Redirect <The Swift Programming Language: Redirect
<>availability-argument → *­
<>platform-name → iOS­ iOSApplicationExtension­
<>platform-name → OSX­ OSXApplicationExtension­
<>platform-name → watchOS­
<>platform-version → decimal-digits <The Swift Programming Language: Redirect
<>platform-version → decimal-digits <The Swift Programming Language: Redirect <The Swift Programming Language: Redirect
<>platform-version → decimal-digits <The Swift Programming Language: Redirect <The Swift Programming Language: Redirect <The Swift Programming Language: Redirect
I’d further argue that the version argument properly adhere to the semver spec: http://semver.org.

The above change, in addition to the change for the if #available statement to not parse the unavailable path would seem to provide the solution you want to have in addition to the solution that many package developers could use as well.

The nice thing is that this could be done in stages:

1. Add support for the language condition and change #available to not parse the non-valid paths
2. Add support for package names
3. Add support for proper semver versioning.

The only breaking change is #1. When/if semver was supported, the version could still take the decimal digits while adding semver support.

-David

···

On Jan 4, 2016, at 4:02 PM, David Farler <dfarler@apple.com> wrote:

We already have @- and #-prefixed availability-like constructs, so I would prefer something more specific to the task – I wouldn't want to dilute the meaning of a package name argument by supplying it with the magic package "swift", for example. Changes to the language can be highly disruptive to all Swift code, so that's why I think it warrants its own build configuration.

David

On Dec 20, 2015, at 10:45 PM, David Owens II via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Then at least everyone can opt-in to using it for availability checks. This should of course tie into the Swift Package Manager and use proper semver syntax (might as well use node’s example: https://docs.npmjs.com/misc/semver\).

Another solution would be to simply factor out the code into separate files and add each to the appropriate build configuration. Then nothing new needs to be added.

-David

On Dec 20, 2015, at 2:01 PM, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Also in future versions features may go away meaning older libraries may assume that greater than swift 2 is all that is needed to imply compatibility. Also libraries may be written against features they may not know which version of swift it will get into. Additionally certain features aren't available across platforms so how do you know what swift 2 means across platforms ?

Swift version conditionals are a useful fallback but we should also try and make feature conditionals a first class citizen too.

I love the @supports syntax in CSS, if we could do that then that would be awesome :) it's a great way of handling implementations across platforms

Sent from my iPhone

On 20 Dec 2015, at 21:00, Andrey Tarantsov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I suspect with the race to a stable language, the plan is to design features as if the language were to stay solid.

Are you implying that Swift 4 will have zero new features? Nothing that libraries will want to use conditionally when available?

A.

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

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

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

The swift package manager is currently considering its own define <#if SWIFT_PACKAGE_MANAGER by drewcrawford · Pull Request #105 · apple/swift-package-manager · GitHub, so it's now the second official project that could benefit from this syntax.

David, any interest in writing this up?

···

On Jan 3, 2016, at 4:48 AM, Goffredo Marocchi <panajev@gmail.com> wrote:

+1 from me as well, supporting conditional compilation when the two versions of foundation differ and may differ for the foreseeable future seems a must on this end.

Sent from my iPhone

On 3 Jan 2016, at 10:12, Drew Crawford via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Big +1.

I've asked specifically to get some kind of conditional compilation on corelibs-foundation <https://lists.swift.org/pipermail/swift-corelibs-dev/Week-of-Mon-20151228/000287.html&gt; being used. corelibs-founcation is currently incompatible with Darwin Foundation, and so it is impractical to make a single codebase build for both.

But building the same application against both Foundations and spotting differences is one of the important ways we're going to spot bugs.

So I think the code quality of Foundation ultimately hinges on getting some feature like this in the language.

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

Definitely a +1 from me.

- Rod

···

On 3 Jan 2016, at 9:48 PM, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org> wrote:

+1 from me as well, supporting conditional compilation when the two versions of foundation differ and may differ for the foreseeable future seems a must on this end.

Sent from my iPhone

On 3 Jan 2016, at 10:12, Drew Crawford via swift-evolution <swift-evolution@swift.org> wrote:

If we are going to support something like this, I’d rather see it be something everyone could leverage as there are many use cases for this feature:

if available("package-name", "1.2.*")
#endif

Big +1.

I've asked specifically to get some kind of conditional compilation on corelibs-foundation being used. corelibs-founcation is currently incompatible with Darwin Foundation, and so it is impractical to make a single codebase build for both.

But building the same application against both Foundations and spotting differences is one of the important ways we're going to spot bugs.

So I think the code quality of Foundation ultimately hinges on getting some feature like this in the language.

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

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