Get rid of #endif


(Brent Royal-Gordon) #1

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


(Richard Ross) #2

-1. Keeping it the current way makes it significantly more obvious where the conditional compilation ends, rather than having to scour for yet another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional compilation as an extra indentation level :slight_smile:

···

--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=


(Félix Cloutier) #3

I don't think that this change can be implemented at all. `#if swift` doesn't parse inactive branches, so you wouldn't be able to disambiguate an `#if swift` end brace from a normal end brace.

Félix

···

Le 8 mars 2016 à 19:33:49, Richard Ross via swift-evolution <swift-evolution@swift.org> a écrit :

-1. Keeping it the current way makes it significantly more obvious where the conditional compilation ends, rather than having to scour for yet another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional compilation as an extra indentation level :slight_smile:
--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e= <https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=>

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


(David Hart) #4

You would at least need #} to disambiguate. With your proposal:

#if FALSE {
if false {
}
print("hello")
#if FALSE {
}
}

This either:
• is invalid syntax
• prints hello
• does nothing

···

Sent from my iPhone

On 09 Mar 2016, at 02:22, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I don't think that this change can be implemented at all. `#if swift` doesn't parse inactive branches, so you wouldn't be able to disambiguate an `#if swift` end brace from a normal end brace.

Félix

Le 8 mars 2016 à 19:33:49, Richard Ross via swift-evolution <swift-evolution@swift.org> a écrit :

-1. Keeping it the current way makes it significantly more obvious where the conditional compilation ends, rather than having to scour for yet another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional compilation as an extra indentation level :slight_smile:
--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=

_______________________________________________
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


(Jean-Daniel) #5

You would at least need #} to disambiguate. With your proposal:

#if FALSE {
if false {
}
print("hello")
#if FALSE {
}
}

This either:
• is invalid syntax
• prints hello
• does nothing

Swift required the block in compiler directive to be syntactically correct. So, you can’t have a dandling "{" and so that sample should not introduced ambiguity.

···

Le 9 mars 2016 à 12:40, David Hart via swift-evolution <swift-evolution@swift.org> a écrit :

Sent from my iPhone
On 09 Mar 2016, at 02:22, Félix Cloutier via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don't think that this change can be implemented at all. `#if swift` doesn't parse inactive branches, so you wouldn't be able to disambiguate an `#if swift` end brace from a normal end brace.

Félix

Le 8 mars 2016 à 19:33:49, Richard Ross via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

-1. Keeping it the current way makes it significantly more obvious where the conditional compilation ends, rather than having to scour for yet another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional compilation as an extra indentation level :slight_smile:
--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e= <https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=>

_______________________________________________
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


(David Hart) #6

But in that case, you are placing #if at the same syntactic level as standard blocks and you loose a fair amount of expressive power.

···

On 10 Mar 2016, at 20:03, Jean-Daniel Dupas <mailing@xenonium.com> wrote:

Le 9 mars 2016 à 12:40, David Hart via swift-evolution <swift-evolution@swift.org> a écrit :

You would at least need #} to disambiguate. With your proposal:

#if FALSE {
if false {
}
print("hello")
#if FALSE {
}
}

This either:
• is invalid syntax
• prints hello
• does nothing

Swift required the block in compiler directive to be syntactically correct. So, you can’t have a dandling "{" and so that sample should not introduced ambiguity.

Sent from my iPhone

On 09 Mar 2016, at 02:22, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I don't think that this change can be implemented at all. `#if swift` doesn't parse inactive branches, so you wouldn't be able to disambiguate an `#if swift` end brace from a normal end brace.

Félix

Le 8 mars 2016 à 19:33:49, Richard Ross via swift-evolution <swift-evolution@swift.org> a écrit :

-1. Keeping it the current way makes it significantly more obvious where the conditional compilation ends, rather than having to scour for yet another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional compilation as an extra indentation level :slight_smile:
--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=

_______________________________________________
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

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


(James Campbell) #7

-1 the #endif is much more clear and since it's so jarring you know its
pre-compiler magic.

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On Fri, Mar 11, 2016 at 7:20 AM, David Hart via swift-evolution < swift-evolution@swift.org> wrote:

But in that case, you are placing #if at the same syntactic level as
standard blocks and you loose a fair amount of expressive power.

On 10 Mar 2016, at 20:03, Jean-Daniel Dupas <mailing@xenonium.com> wrote:

Le 9 mars 2016 à 12:40, David Hart via swift-evolution < > swift-evolution@swift.org> a écrit :

You would at least need #} to disambiguate. With your proposal:

#if FALSE {
if false {
}
print("hello")
#if FALSE {
}
}

This either:
• is invalid syntax
• prints hello
• does nothing

Swift required the block in compiler directive to be syntactically
correct. So, you can’t have a dandling "{" and so that sample should not
introduced ambiguity.

Sent from my iPhone
On 09 Mar 2016, at 02:22, Félix Cloutier via swift-evolution < > swift-evolution@swift.org> wrote:

I don't think that this change can be implemented at all. `#if swift`
doesn't parse inactive branches, so you wouldn't be able to disambiguate an
`#if swift` end brace from a normal end brace.

Félix

Le 8 mars 2016 à 19:33:49, Richard Ross via swift-evolution < > swift-evolution@swift.org> a écrit :

-1. Keeping it the current way makes it significantly more obvious where
the conditional compilation ends, rather than having to scour for yet
another pesky curly brace.

Additionally, some of us are logical and prefer not to use conditional
compilation as an extra indentation level :slight_smile:
--
Richard

On Mar 8, 2016, at 4:23 PM, Brent Royal-Gordon via swift-evolution < > swift-evolution@swift.org> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org

https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Devolution&d=CwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=Ezje1IF3xGXfUMfsj4fBc7oM7BcJys1dhQ6psfXzLMU&m=KpVD5NRN240WmQvnHJitBkkgyBtlHU87STAlrcfVNSA&s=V6Bvu749V2ofSYff-m5YKMX_g5Yr48jKkjCeBANWe4w&e=

_______________________________________________
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

_______________________________________________
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