[swift-evolution] Get rid of #endif
Brent Royal-Gordon
brent at architechies.com
Tue Mar 8 18:23:46 CST 2016
Swift inherited an odd preprocessor-related inconsistency from C, and I'm wondering if we should change it.
Swift and C both use curly-bracket blocks to delimit if statements and other runtime control flow:
if foo {
blah
}
else {
yadda
}
However, the preprocessor/build configuration equivalent uses keywords in the style of languages like BASIC:
#if FOO
blah
#else
blah
#endif
In addition to the inconsistency, I consider this to have several concrete disadvantages:
- It leaves the preferred indentation of a conditional block ambiguous. Some people indent, others don't.
- It gives us no syntax to build on for other things that should be "scoped". For instance, clang's `#pragma clang diagnostic push/pop` is as strange as it is because there's no sensible way to delimit a block structure.
C justifies this because the preprocessor is a separate pass with its own rules, but Swift does not have this limitation.
Therefore, I suggest we switch to this syntax:
#if FOO {
blah
}
#else {
blah
}
That gives us a basis to cleanly extend compiler directives to add new features. For instance, the #suppress directive discussed in the "[Idea] #suppress(warning-identifier)" could be given a syntax like this:
#suppress self-in-closure {
blah
}
If their design ends up being purely compile-time with no runtime impact, we might even consider using this syntax for behaviors:
#behavior var lazy<Value>: Value {
private var value: Value?
get {
if let value = value {
return value
}
let newValue = initialValue
value = newValue
return newValue
}
set {
value = newValue
}
}
There are two disadvantages I can identify:
- The fact that a particular } is associated with a compiler directive may not be immediately obvious when reading code.
- `#if swift(...)` may not be able to correctly parse the close of the block if unrecognized new language features inside the block appear to unbalance the curly brackets. (For instance, if a new literal syntax is used to quote a closing curly and older Swift compilers don't recognize it.)
If these problems are considered serious enough, an alternative would be to use `#}` to indicate the close of the compiler directive's scope. This is obviously not an ordinary curly bracket and is unlikely to appear in source for any other reason.
--
Brent Royal-Gordon
Architechies
More information about the swift-evolution
mailing list