# Syntax suggestion: end\<control\>

**URL:** <https://discourse.julialang.org/t/syntax-suggestion-end-control/8605>\
**Category:** Internals & Design\
**Created:** [January 26, 2018, 12:26am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605 "2018-01-26T00:26:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [January 26, 2018, 12:26am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/1 "2018-01-26T00:26:49Z")

</div>

end could be a synonym for end. so

```julia
if (a=b)
   continue
endif

```

would be equivalent to

```julia
if (a=b)
   continue
end

```

In the long-term, the compiler could check whether the control statement is aligned to its end, too. This can be a useful feature for finding bugs in a long program with a lot of control-nesting.

if this has already been discussed, or implemented (and I don’t know), please ignore this post.

---

<div class="post-metadata">

**Author:** ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)\
**Post date:** [January 26, 2018, 1:23am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/2 "2018-01-26T01:23:50Z")

</div>

You could do something like this, just as a proof of concept (not taking `elseif`/`else` branches into account), similar macros could be done for the other type of blocks:

```julia
julia> @eval macro $(:if)(condition, expression, terminator::Symbol)
           terminator ≠ :endif && error()
           quote
               if $condition
                   $expression
               end
           end |> esc
       end
@if (macro with 1 method)

julia> x = 42
42

julia> @if x == 42 (
           info("yep!")
       ) endif
INFO: yep!

julia> @macroexpand @if x == 42 (
           info("yep!")
       ) endif
quote # REPL[9], line 4:
    if x == 42 # REPL[9], line 5:
        info("yep!")
    end
end

```

But then again in Julia a lot of control nesting can become a lot of multiple dispatch instead, I would refactor such a long `if` block. In Julia you can have pretty much any syntax you like and in a package.

I just wish there where some kind of macro line continuation syntax or semantics, but the parenthesis do the job here (instead of a `begin ... end`, which would defeat the purpose of the trailing `endif`).

Also you could always do:

```julia
if (a=b)
   continue
end # if

```

😛

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [January 26, 2018, 8:43am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/3 "2018-01-26T08:43:43Z")

</div>

It would be fairly straightforward to write a short function that parses a julia file and throws an error message whenever `end#if` closes a block that was not opened by an `if`, etc. Then let `runtests.jl` run this on every file in your package before they are loaded.

(The `parse()` function does not seem to keep track of comments, but it might work to search-replace `end#if` to `end;Expr(:meta,:if);` before parsing, and then search the AST for this pattern.)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 26, 2018, 11:42am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/4 "2018-01-26T11:42:32Z")

</div>

> [@Per](#):
>
> would be fairly straightforward to write a short function that parses a julia file and throws an error message

Perhaps the [Lint.jl](https://github.com/tonyhffong/Lint.jl) authors could be convinced to add this as an option.

But I am skeptical of the utility of this feature. And `end` which is very far from its opening pair already indicates code smell and suggests refactoring. Same applies to unclosed opening constructs (`for`, `begin`, `let`, `function`, …) and similar stuff. Emacs immediately starts to ~~passive-aggressively~~ misindent everything once I forget to match an opening, so I rarely ever run into making this kind of error.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 26, 2018, 1:08pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/5 "2018-01-26T13:08:25Z")

</div>

> [@Tamas\_Papp](#):
>
> And end which is very far from its opening pair already indicates code smell and suggests refactoring

This is a good recommendation for `function` and control block but it is certainly not true for types def with many constructors or (nested) modules. clang format provide similar function for namespace name.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 26, 2018, 1:28pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/6 "2018-01-26T13:28:05Z")

</div>

I would suspect the need for many inner constructors too; or long implementations for those constructors—if complicated calculations or checks are needed, they should be refactored into a separate function, or possible multiple small functions.

I have to admit though that lately my programming style has been influenced a lot by Robert C. Martin’s “Clean Code” and related books, and tend to write much shorter functions. I recognize that this is not the style favored by all `Base` contributors.

Perhaps a concrete example to discuss would be interesting.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [January 26, 2018, 3:44pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/7 "2018-01-26T15:44:24Z")

</div>

ok, we can disagree on the benefit. it may rank from zero to medium. it is certainly not great.

but what is the cost here?

- complexity increase of compiler? no.
- complexity increase of user code? no.
- learning curve? no.
- pollution of namespace? endif, endwhile, endfor … hopefully not common. moreover, if someone used them, their code would probably be harder and not easier to understand.

what have I forgotten?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 26, 2018, 3:51pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/8 "2018-01-26T15:51:36Z")

</div>

At the risk of being too presumptive, (because there certainly are pieces of code out there that are just really complicated and hard to reorganize in a more succinct way) I find that _usually_ if your code contains so many nested blocks that you can’t keep track of where they close it is probably a sign that you should reorganize your code into separate functions.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [January 26, 2018, 4:14pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/9 "2018-01-26T16:14:29Z")

</div>

What’s the cost? I think I’d disagree with just about every one of your items on that bulleted list — sure, none of them are huge costs, but they are definitely costs none-the-less.

The biggest cost, though? Developer time. Not only would this cost the time to implement it in base Julia itself, but it’d also require every single Julia grammar file to be updated for proper highlighting and indentation. And then there’d be the “forever” cost of folks who believe that this is the “better” way of spelling `end` slowly converting `end`s to `endif`s, `endwhile`s, and `endbegins` because “it’s safer” throughout the ecosystem.

Plus that last one, `endbegin` would just be bizarre.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [January 26, 2018, 4:36pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/10 "2018-01-26T16:36:20Z")

</div>

then I was wrong.

I judged the cost to be smaller than the benefit. I am not a developer; I thought it would just be updating a few tables—an hour for the alias. (not yet checking proper closing.) . about the same time as discussing it 😉

(the syntax highlighting and indentation is a reason why I preferred it in the core language. and it is a little safer, indeed, though trivially so. hope most would recognize it. endbegin indeed seems bizarre, but then end would still work just the same and seem more natural.)

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [January 29, 2018, 3:53am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/11 "2018-01-29T03:53:31Z")

</div>

> [@mbauman](#):
>
> Plus that last one, endbegin would just be bizarre.

I think this says more about the naming of `begin ... end` blocks.  
The naming is quite unspecific, `begin` what?

Perhaps:

```julia
block
   ...
endblock

```

Although I think ending all constructs with `end` is fine.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 7, 2018, 3:25am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/12 "2018-03-07T03:25:44Z")

</div>

now that I have spent another month in Julia, I think my original suggestion was not so bad, after all. See, we already have many functions aliased, or near-aliased (such as `readcsv` instead of `readdlm`). Aliasing (without checking) a couple of end_variants_ to end is not against the spirit of many other existing aliases; and some authors (=me) like the mnemonic. If we had a C-like preprocessor, I could do this myself:

```julia
#define endfor end
#define endwhile end
#define endfunction end
#define endlet end
#define enddo end
#define endif end

```

matt: with respect, I disagree that this is more harmful than the dozens of other function aliases that we have. Anyone who likes a pure end can just use it. Up to them. It’s just a pure alias. (if julialint eventually wants to check for matching, up to julialint.) and although I do not know the julia internals, I would hope that these aliases would be easy to code.

it then allows one-liners that one could not otherwise one-line with the `end#while` construct:

```julia
julia> open("/etc/passwd","r") do fout;	while (!eof(fout)); endwhile; enddo

```

ok, I have said my spiel. Up to the julia team…

---

<div class="post-metadata">

**Author:** ![ssfrr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ssfrr/32/3736_2.png) [@ssfrr](https://discourse.julialang.org/u/ssfrr)\
**Post date:** [March 7, 2018, 4:15am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/13 "2018-03-07T04:15:03Z")

</div>

you don’t need `endwhile` and `enddo` to have nested blocks in one-liners:

```julia
julia> for i in 1:10 if isodd(i) println(i) end end
1
3
5
7
9

```

(not that I’d generally advise writing code like this)

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [March 7, 2018, 5:15am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/14 "2018-03-07T05:15:32Z")

</div>

> [@ssfrr](#):
>
> julia\> for i in 1:10 if isodd(i) println(i) end end

I do not need it. but if I want it (and I sometimes do!), it is a little more expressive:

> [@ssfrr](#):
>
> julia\> for i in 1:10 if isodd(i) println(i) endif endfor

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [March 12, 2018, 12:50am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/15 "2018-03-12T00:50:40Z")

</div>

This can’t be done with a macro unless one uses different words for if, for, while, do, etc. Correct?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 12, 2018, 7:06am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/16 "2018-03-12T07:06:35Z")

</div>

AFAICT you are correct, the parser will complain that the expression is incomplete before it gets to the macro.

---

<div class="post-metadata">

**Author:** ![NaOH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/naoh/32/5632_2.png) [@NaOH](https://discourse.julialang.org/u/NaOH)\
**Post date:** [March 14, 2018, 8:36am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/17 "2018-03-14T08:36:34Z")

</div>

> [@Mason](#):
>
> This can’t be done with a macro unless one uses different words for if, for, while, do, etc. Correct?

It can be done, see my answer above:

- [Syntax suggestion: end\<control\> - #2 by NaOH](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/2)

> [@Tamas\_Papp](#):
>
> AFAICT you are correct, the parser will complain that the expression is incomplete before it gets to the macro.

```julia
julia> keywords = [:if, :for, :while, :do]
4-element Array{Symbol,1}:
 :if
 :for
 :while
 :do

julia> for keyword in keywords
           @eval macro $(keyword)(block, terminator::Symbol)
               terminator ≠ Symbol(:end, $(Meta.quot(keyword))) && error()
               esc(:($block))
           end
       end

julia> @do (
           println("My do-enddo block.")
       ) enddo
My do-enddo block.

julia> @for true endfor
true

julia> @while 1 + 1 endwhile
2

julia> @while 1 + 1 endfor
ERROR: LoadError:
Stacktrace:
 [1] error() at .\error.jl:44
 [2] @while(::LineNumberNode, ::Module, ::Any, ::Symbol) at .\REPL[24]:3
in expression starting at REPL[28]:1

```

Is that what you mean?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 14, 2018, 8:53am UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/18 "2018-03-14T08:53:02Z")

</div>

What I meant is that I don’t think you can do

```julia
@some_macro for ... endfor

```

because it will not be parsed without an `end`. Of course if you replace `for`, this is not a constraint.

---

<div class="post-metadata">

**Author:** ![iwelch](https://avatars.discourse-cdn.com/v4/letter/i/8c91f0/32.png) [@iwelch](https://discourse.julialang.org/u/iwelch)\
**Post date:** [October 14, 2018, 11:26pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/19 "2018-10-14T23:26:28Z")

</div>

it’s not really what I mean. what I would like to be able to write is

```julia
julia> for i=1:10 if (i>5) println(i) endif endfor

```

Even with the @ version, I am already flunking on just the for loop:

```julia
julia> @for i=1:10; println(i); endfor
ERROR: LoadError: MethodError: no method matching @for(::LineNumberNode, ::Module, ::Expr, ::Expr, ::Symbol)
Closest candidates are:
  @for(::LineNumberNode, ::Module, ::Any, ::Symbol) at REPL[2]:3
in expression starting at REPL[9]:1

```

I truly would like the dumbest preprocessor directive possible and stick it into my startup.jl:

```nohighlight
#define endfor end
#define endif end

```

and. of course, I still disagree that this feature would impose any cost on users that chose not to employ it.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 14, 2018, 11:36pm UTC](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605/20 "2018-10-14T23:36:48Z")

</div>

> [@iwelch](#):
>
> I truly would like the dumbest preprocessor directive possible and stick it into my startup.jl:

And I’ll remind you that being able to do that is exactly the reason why C preprocessors are so terrible.

> [@iwelch](#):
>
> any cost on users that chose not to employ it.

Only if everyone can also choose to not use or see any code that uses it.

[Next page](https://discourse.julialang.org/t/syntax-suggestion-end-control/8605.md?page=2)
