Optional "endfor", "endif", etc after closing "}"


(Amir Michail) #1

Unlike something like “} // if”, the compiler would actually check "} endif” and report an error if “}” doesn’t close the expected construct.


(Amir Michail) #2

Unlike something like “} // if”, the compiler would actually check "} endif” and report an error if “}” doesn’t close the expected construct.

Or perhaps more elegantly (again, it’s optional):

if ... {
   …
if }

for ... {
   …
for }
etc.

···

On Dec 8, 2015, at 8:42 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

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


(Andrew Brown) #3

+1

Anything that supports developers is worth it.
Can't say I like the syntax but I'll take whatever is agreed.

ABR.

···

On 8 Dec 2015, at 14:43, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 8, 2015, at 8:42 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Unlike something like “} // if”, the compiler would actually check "} endif” and report an error if “}” doesn’t close the expected construct.

Or perhaps more elegantly (again, it’s optional):

if ... {
  …
if }

for ... {
  …
for }
etc.

_______________________________________________
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


#4

I’m against such a change. It creates a lot of visual noise and ceremony around the creation of every scope.

It would be possible for a custom linter to enforce “// if” comments, though I’ve never found these kinds of annotations useful—they seem to be added as code grows where refactoring/reorganization would probably be the better route.

Stephen

···

On Dec 12, 2015, at 7:54 AM, Andrew Brown via swift-evolution <swift-evolution@swift.org> wrote:

+1

Anything that supports developers is worth it.
Can't say I like the syntax but I'll take whatever is agreed.

ABR.

On 8 Dec 2015, at 14:43, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 8, 2015, at 8:42 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Unlike something like “} // if”, the compiler would actually check "} endif” and report an error if “}” doesn’t close the expected construct.

Or perhaps more elegantly (again, it’s optional):

if ... {

if }

for ... {

for }
etc.

_______________________________________________
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


(Amir Michail) #5

+1

Anything that supports developers is worth it.
Can't say I like the syntax but I'll take whatever is agreed.

What about this syntax?

for … {
  if … {
    …
  } /if
} /for

···

On Dec 12, 2015, at 7:54 AM, Andrew Brown <a.br@me.com> wrote:

ABR.

On 8 Dec 2015, at 14:43, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 8, 2015, at 8:42 AM, Amir Michail via swift-evolution <swift-evolution@swift.org> wrote:

Unlike something like “} // if”, the compiler would actually check "} endif” and report an error if “}” doesn’t close the expected construct.

Or perhaps more elegantly (again, it’s optional):

if ... {

if }

for ... {

for }
etc.

_______________________________________________
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


(Marc Knaup) #6

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the
developer thinks about annotating the closing curly brace then they should
instead break it down into smaller pieces. Move parts into separate
functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function
names will aid as additional documentation.

···

On Sat, Dec 12, 2015 at 2:19 PM, Amir Michail via swift-evolution < swift-evolution@swift.org> wrote:

> On Dec 12, 2015, at 7:54 AM, Andrew Brown <a.br@me.com> wrote:
>
> +1
>
> Anything that supports developers is worth it.
> Can't say I like the syntax but I'll take whatever is agreed.

What about this syntax?

for … {
  if … {
    …
  } /if
} /for

>
> ABR.
>
>> On 8 Dec 2015, at 14:43, Amir Michail via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>>
>>> On Dec 8, 2015, at 8:42 AM, Amir Michail via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> Unlike something like “} // if”, the compiler would actually check "}
endif” and report an error if “}” doesn’t close the expected construct.
>>
>> Or perhaps more elegantly (again, it’s optional):
>>
>> if ... {
>> …
>> if }
>>
>> for ... {
>> …
>> for }
>> etc.
>>
>>
>>> _______________________________________________
>>> 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


(Jerome Duquennoy) #7

What about this syntax?

for … {
if … {
   …
} /if
} /for

I have the feeling we are double defining the blocs here :
for ... /for is enough to have the beginning and the end if the bloc, and so is { ... }.

So I think that syntax is redundant.

I also think that such a solution would only solve half of the readability problem in a complex code.

Consider for exemple this piece of pseudo code :

···

------------------------------------------------------
if (...) {
  if (...) {
    for (...) {
      // insert here a big number of lines
    }
  }
  
  if (...) {
    for (...) {
      // insert here a big number of lines
    }
  }
}
------------------------------------------------------
This thing end up with 3 closing block in the end, and if you have enough lines of code instead of the two comments, you don't see the beginning of those any more.
Considering the proposed syntax, you end up with that :

------------------------------------------------------
if (...) {
  if (...) {
    for (...) {
      // insert here a big number of lines
    } /for
  } /if
  
  if (...) {
    for (...) {
      // insert here a big number of lines
    } /for
  } / if
} /if
------------------------------------------------------

You have a bit more info, for sure. But not yet enough to clearly identify what bloc is being closed by a given line. To have it all, you would have to copy the whole condition ... but that would be copy / past.

In the end I have the feeling the advantage of the proposal is not huge, whatever the syntax. Not enough to add new keywords.
I agree with Marc that refactoring seems a good solution when it becomes hard to know what block ends where.

Jerome


(Greg Parker) #8

Or a better editor. Modern code editors have affordances to improve readability of such code, such as highlighting matching braces, coloring nested scopes, or folding and unfolding scopes.

One advantage of the editor-based approaches is that they don't make editing more difficult. You don't need to write any scope annotations and you don't need to keep them up to date as the code changes.

···

On Dec 12, 2015, at 5:41 AM, Al Skipp via swift-evolution <swift-evolution@swift.org> wrote:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the developer thinks about annotating the closing curly brace then they should instead break it down into smaller pieces. Move parts into separate functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of blocks to assist comprehension, then the code needs refactoring.

--
Greg Parker gparker@apple.com <mailto:gparker@apple.com> Runtime Wrangler


(Al Skipp) #9

I completely agree.

If code becomes so impenetrable that you need to annotate the end of blocks to assist comprehension, then the code needs refactoring. Adding a syntactical crutch that encourages you to chop off your own leg, doesn’t seem like a good idea.

···

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution <swift-evolution@swift.org> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the developer thinks about annotating the closing curly brace then they should instead break it down into smaller pieces. Move parts into separate functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function names will aid as additional documentation.


(Thorsten Seitz) #10

I completely agree with Marc and Al.

-Thorsten

···

Am 12.12.2015 um 14:41 schrieb Al Skipp via swift-evolution <swift-evolution@swift.org>:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the developer thinks about annotating the closing curly brace then they should instead break it down into smaller pieces. Move parts into separate functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of blocks to assist comprehension, then the code needs refactoring. Adding a syntactical crutch that encourages you to chop off your own leg, doesn’t seem like a good idea.


(Etan Kissling) #11

Counter-proposal that eliminates the nested ifs.

If I have functions with long if blocks, I typically use switches on named tuples.

switch (condition1: ..., condition2: ...) {
    case (condition1: false, condition2: true):
        ...

    case (condition1: _, condition2: false):
        ...

    case (condition1: true, condition2: true) where condition3:
        ...

    case (condition1: true, condition2: true):
        ...
}

This way, you are reminded after each long block about your current scope, and the compiler checks for unhandled cases.

Etan

···

On 12 Dec 2015, at 22:35, Greg Parker via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 12, 2015, at 5:41 AM, Al Skipp via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the developer thinks about annotating the closing curly brace then they should instead break it down into smaller pieces. Move parts into separate functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of blocks to assist comprehension, then the code needs refactoring.

Or a better editor. Modern code editors have affordances to improve readability of such code, such as highlighting matching braces, coloring nested scopes, or folding and unfolding scopes.

One advantage of the editor-based approaches is that they don't make editing more difficult. You don't need to write any scope annotations and you don't need to keep them up to date as the code changes.

--
Greg Parker gparker@apple.com <mailto:gparker@apple.com> Runtime Wrangler

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


(Marc Knaup) #12

This changes the behavior though.

In "if cond1 && cond2" cond2 is only evaluated iff cond1 is true.
Using switch both conditions will be evaluated right away unconditionally.

···

On Mon, Dec 14, 2015 at 12:48 PM, Etan Kissling via swift-evolution < swift-evolution@swift.org> wrote:

Counter-proposal that eliminates the nested ifs.

If I have functions with long if blocks, I typically use switches on named
tuples.

switch (condition1: ..., condition2: ...) {
    case (condition1: false, condition2: true):
        ...

    case (condition1: _, condition2: false):
        ...

    case (condition1: true, condition2: true) where condition3:
        ...

    case (condition1: true, condition2: true):
        ...
}

This way, you are reminded after each long block about your current scope,
and the compiler checks for unhandled cases.

Etan

On 12 Dec 2015, at 22:35, Greg Parker via swift-evolution < > swift-evolution@swift.org> wrote:

On Dec 12, 2015, at 5:41 AM, Al Skipp via swift-evolution < > swift-evolution@swift.org> wrote:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution < > swift-evolution@swift.org> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the
developer thinks about annotating the closing curly brace then they should
instead break it down into smaller pieces. Move parts into separate
functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function
names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of
blocks to assist comprehension, then the code needs refactoring.

Or a better editor. Modern code editors have affordances to improve
readability of such code, such as highlighting matching braces, coloring
nested scopes, or folding and unfolding scopes.

One advantage of the editor-based approaches is that they don't make
editing more difficult. You don't need to write any scope annotations and
you don't need to keep them up to date as the code changes.

--
Greg Parker gparker@apple.com Runtime Wrangler

_______________________________________________
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


(Etan Kissling) #13

That's why I've included the "case ... where" case :slight_smile: condition3 is only evaluated after 1/2.

···

On 14 Dec 2015, at 12:59, Marc Knaup <marc@knaup.koeln<mailto:marc@knaup.koeln>> wrote:

This changes the behavior though.

In "if cond1 && cond2" cond2 is only evaluated iff cond1 is true.
Using switch both conditions will be evaluated right away unconditionally.

On Mon, Dec 14, 2015 at 12:48 PM, Etan Kissling via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:
Counter-proposal that eliminates the nested ifs.

If I have functions with long if blocks, I typically use switches on named tuples.

switch (condition1: ..., condition2: ...) {
    case (condition1: false, condition2: true):
        ...

    case (condition1: _, condition2: false):
        ...

    case (condition1: true, condition2: true) where condition3:
        ...

    case (condition1: true, condition2: true):
        ...
}

This way, you are reminded after each long block about your current scope, and the compiler checks for unhandled cases.

Etan

On 12 Dec 2015, at 22:35, Greg Parker via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

On Dec 12, 2015, at 5:41 AM, Al Skipp via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution <swift-evolution@swift.org<mailto:swift-evolution@swift.org>> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that the developer thinks about annotating the closing curly brace then they should instead break it down into smaller pieces. Move parts into separate functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of blocks to assist comprehension, then the code needs refactoring.

Or a better editor. Modern code editors have affordances to improve readability of such code, such as highlighting matching braces, coloring nested scopes, or folding and unfolding scopes.

One advantage of the editor-based approaches is that they don't make editing more difficult. You don't need to write any scope annotations and you don't need to keep them up to date as the code changes.

--
Greg Parker gparker@apple.com<mailto:gparker@apple.com> Runtime Wrangler

_______________________________________________
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


(Andrew Bennett) #14

I agree with Stephen, I think it will probably just make more clutter.
However if you did want to do it a linter is probably a better option.

I haven't used it yet, but I've heard this one is good:
* https://github.com/realm/SwiftLint
* Another alternative: http://swiftcleanapp.com

Among other really things it would allow you to enforce style choices on
your code. You could make it a compile time error if an if-statement wasn't
followed by a "} // if".

I'm not sure about the second tool, but you can add custom rules to the
first. This may be a good starting point:
https://github.com/realm/SwiftLint/blob/master/Source/SwiftLintFramework/Rules/ControlStatementRule.swift

···

On Tue, Dec 15, 2015 at 12:22 AM, Etan Kissling via swift-evolution < swift-evolution@swift.org> wrote:

That's why I've included the "case ... where" case :slight_smile: condition3 is only
evaluated after 1/2.

On 14 Dec 2015, at 12:59, Marc Knaup <marc@knaup.koeln> wrote:

This changes the behavior though.

In "if cond1 && cond2" cond2 is only evaluated iff cond1 is true.
Using switch both conditions will be evaluated right away unconditionally.

On Mon, Dec 14, 2015 at 12:48 PM, Etan Kissling via swift-evolution < > swift-evolution@swift.org> wrote:

Counter-proposal that eliminates the nested ifs.

If I have functions with long if blocks, I typically use switches on
named tuples.

switch (condition1: ..., condition2: ...) {
    case (condition1: false, condition2: true):
        ...

    case (condition1: _, condition2: false):
        ...

    case (condition1: true, condition2: true) where condition3:
        ...

    case (condition1: true, condition2: true):
        ...
}

This way, you are reminded after each long block about your current
scope, and the compiler checks for unhandled cases.

Etan

On 12 Dec 2015, at 22:35, Greg Parker via swift-evolution < >> swift-evolution@swift.org> wrote:

On Dec 12, 2015, at 5:41 AM, Al Skipp via swift-evolution < >> swift-evolution@swift.org> wrote:

On 12 Dec 2015, at 13:31, Marc Knaup via swift-evolution < >> swift-evolution@swift.org> wrote:

I'm also against any kind of markers to annotate the end of a block.

If the code inside a if/guard/loop/do/func/var/… block is so long that
the developer thinks about annotating the closing curly brace then they
should instead break it down into smaller pieces. Move parts into separate
functions and replace it with calls to these functions.
This makes the block shorter, much easier to understand and the function
names will aid as additional documentation.

I completely agree.

If code becomes so impenetrable that you need to annotate the end of
blocks to assist comprehension, then the code needs refactoring.

Or a better editor. Modern code editors have affordances to improve
readability of such code, such as highlighting matching braces, coloring
nested scopes, or folding and unfolding scopes.

One advantage of the editor-based approaches is that they don't make
editing more difficult. You don't need to write any scope annotations and
you don't need to keep them up to date as the code changes.

--
Greg Parker gparker@apple.com Runtime Wrangler

_______________________________________________
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