For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

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.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

I had considered this format but I don't think it reads as well as you'd expect for a version. It kind of makes it seem like each component is an independent argument, each with possibly a different meaning. It makes sense from a parsing point of view but I think we should allow folks to write it the same way they'd write it in normal prose, since it's not much more effort.

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

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.

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

I had considered this format but I don't think it reads as well as you'd expect for a version. It kind of makes it seem like each component is an independent argument, each with possibly a different meaning. It makes sense from a parsing point of view but I think we should allow folks to write it the same way they'd write it in normal prose, since it's not much more effort.

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

I had considered this format but I don't think it reads as well as you'd expect for a version. It kind of makes it seem like each component is an independent argument, each with possibly a different meaning. It makes sense from a parsing point of view but I think we should allow folks to write it the same way they'd write it in normal prose, since it's not much more effort.

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

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.

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.

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.

#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.

A bare 2.2 will work. Right now, 2.2.2 won't lex because of a requirement that member access of a numeric literal be named but, if we decide down the road that we really, really need another version component, it wouldn't be a ton of work to give an exception when parsing an #if config.

I had considered this format but I don't think it reads as well as you'd expect for a version. It kind of makes it seem like each component is an independent argument, each with possibly a different meaning. It makes sense from a parsing point of view but I think we should allow folks to write it the same way they'd write it in normal prose, since it's not much more effort.

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.

David know this already, but I’m a huge fan of this feature.

-Chris

Yep, you took the words out of my mouth re: the version components. If two components are enough though, then we should totally drop the quotes.

For Swift 2.2, I'd like to add the following build configuration to check for the Swift language version. This is meant to be a short proposal, so let's start with a simple example, compiling with the 2.2 compiler:

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

The semantics of the build configuration is, "is the Swift language version at least X?". If it is, the active block is parsed and compiled into your program. Like the other build configuration blocks, this isn't line-based, but break on whole statements and declarations. Unlike the other build configurations, however, the inactive block will not parse or emit syntax errors, so you can include syntax for older Swift language revisions in the same file if you prefer.

It sounds like a lot of folks have been wanting something like this, which is why I'm suggesting it for the Swift 2.2 release. I'm curious to hear your feedback!

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:

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.

#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.

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:

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.

#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.

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 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.

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.

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.

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> 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.

That is a fair point of comparison, although this should work for both statements and declarations, in which case the extra attribute style would be redundant. Maybe the implicit >= is good enough. I'd like to keep it as simple as possible.

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 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.