Proposal: use continue keyword instead of fallthrough

848 views
Skip to first unread message

Carlos C

unread,
Jan 18, 2012, 6:41:09 AM1/18/12
to golang-nuts

Good morning gophers,

The email's subject says it all.
I constantly read that programming language's complexity is measured
by its keyword number so I thought of proposing this.


So, why I propose this?
Switch now is visually nice, lacks of breaks, yay! and it has
wonderful and powerful features like "empty" switch.

The average length of a keyword in Go is 5.16 chars long; fallthrough
has 11 chars, seems a bit long for me.


What about lexical sense?
I'm not english but I would still understand what does continue do
inside switch case's.

Fallthrough is a bit more intuitive to readers because they can
understand it as:
" I'm on waterfall of cases and when I'm done with this one I will
fall into the next one ".
It feels like a japanese master who is teaching you how to get godlike
zen powers.

But this is code you can't fall into nothing, you call or get called.
You repeat things in a loop. You start or stop things.
Reminds me Java verbosiness.


Benefits, as I see them:
- Non-english gophers, like me, will thank you. Longer words in a
foreign language are harder to write.
- One less keyword, yay! Just 29 more to learn them all.
- 3 chars less to write on each fallthrough
- Go's parser shouldn't freak out. I suppose continue-s inside for are
checked by scope so it shouldn't break nothing.


Counterparts:
- That's up to you gophers.


An example:

package main

import "fmt"

func main() {
k := 6
switch k {
case 4: fmt.Println("was <= 4"); continue;
case 5: fmt.Println("was <= 5"); continue;
case 6: fmt.Println("was <= 6"); continue;
case 7: fmt.Println("was <= 7"); continue;
case 8: fmt.Println("was <= 8"); continue;
default: fmt.Println("default case")
}
}


About me:
I'm just a tadpole compared to Commander Pike, just to name someone
"big".

My background is mostly web-based (Python, HTML & yadda yadda...) two
years ago I started doing some C++ & Java at college. Most of the time
I use maps instead of switches, but then I moved to Go and it was like
rediscovering a concept that WAS just another, more verbose and
restricted way, of writing a lot of if-elses. Java switch is awful.


Hope you like it.

Let the gopher be with you!


Switch example taken from:
http://golangtutorials.blogspot.com/2011/06/control-structures-go-switch-case.html

chris dollin

unread,
Jan 18, 2012, 7:06:37 AM1/18/12
to Carlos C, golang-nuts
On 18 January 2012 11:41, Carlos C <php...@gmail.com> wrote:
>
> Good morning gophers,
>
> The email's subject says it all.
> I constantly read that programming language's complexity is measured
> by its keyword number

It isn't. Not in the sense that "more keywords generate more complexity":
it more that the more complex language may need more keywords.

Which means that just reducing the keyword count doesn't make a
language less complex.

Chris

--
Chris "allusive" Dollin

Jan Mercl

unread,
Jan 18, 2012, 7:12:31 AM1/18/12
to golan...@googlegroups.com
On Wednesday, January 18, 2012 12:41:09 PM UTC+1, Carlos C wrote:

The email's subject says it all.

You can't alias continue and fallthrough:

package main

func main() {
        for {
                switch {
                case 1 > 2:
                        continue
                case 3 < 4:
                        fallthrough
                case 5 > 6:
                        println("OK")
                        return        
                }
        }
}

Note how continue has completely different effect than fallthrough in the above program.

 

chris dollin

unread,
Jan 18, 2012, 7:14:47 AM1/18/12
to Carlos C, golang-nuts
On 18 January 2012 11:41, Carlos C <php...@gmail.com> wrote:
>
> Good morning gophers,
> The average length of a keyword in Go is 5.16 chars long; fallthrough
> has 11 chars, seems a bit long for me.

Zipf's law applies.

>
> What about lexical sense?
> I'm not english but I would still understand what does continue do
> inside switch case's.

continue /already/ means something inside a switch case: it means
to continue the enclosing loop. [If there is one.] Your suggestion could
change the meaning of existing code. [You'd have to add labels to
all fors with nested switches.]

`continue` is a jump away (to the end-of-loop code). `fallthrough`
is a DON'T-jump-away. Using `contune` for `fallthrough` makes that
distinction harder to see,

It doesn't matter that `fallthrough` is a long keyword; you're not
going to be writing it often. If ever.

>        switch k {
>        case 4: fmt.Println("was <= 4"); continue;
>        case 5: fmt.Println("was <= 5"); continue;
>        case 6: fmt.Println("was <= 6"); continue;
>        case 7: fmt.Println("was <= 7"); continue;
>        case 8: fmt.Println("was <= 8"); continue;
>        default: fmt.Println("default case")
>        }
> }

Examples for new constructs should be sane.

Gustavo Niemeyer

unread,
Jan 18, 2012, 8:58:30 AM1/18/12
to Carlos C, golang-nuts
> The email's subject says it all.

The point of "fallthrough" is that in all languages with switch
support it is the exception rather than the rule, and it is a rare
case too, so having fallthrough spelled makes sense, and its length
isn't a problem in practice.

--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/plus
http://niemeyer.net/twitter
http://niemeyer.net/blog

-- I'm not absolutely sure of anything.

unread,
Jan 18, 2012, 9:21:04 AM1/18/12
to golang-nuts
On Jan 18, 12:41 pm, Carlos C <php....@gmail.com> wrote:
> The average length of a keyword in Go is 5.16 chars long

5.16? How did you compute it?

Maxim Pimenov

unread,
Jan 18, 2012, 9:59:22 AM1/18/12
to ⚛, golang-nuts
5.16? How did you compute it?

I believe he is right: http://play.golang.org/p/887yaQzr-i

roger peppe

unread,
Jan 18, 2012, 10:04:16 AM1/18/12
to Maxim Pimenov, ⚛, golang-nuts
you should do an average taking into account relative frequency
of keyword use, i think.

Aram Hăvărneanu

unread,
Jan 18, 2012, 10:18:04 AM1/18/12
to roger peppe, Maxim Pimenov, ⚛, golang-nuts
> you should do an average taking into account relative frequency
> of keyword use, i think.

Or, you can do what I do. Not care :-).

Such metrics are meaningless.

--
Aram Hăvărneanu

John Asmuth

unread,
Jan 18, 2012, 10:21:08 AM1/18/12
to golan...@googlegroups.com
+1 for not confusing causation with correlation.

Steve McCoy

unread,
Jan 18, 2012, 10:23:08 AM1/18/12
to golan...@googlegroups.com
It's missing a few, too. I'm a big fan of the "despiteallobjections" keyword.

si guy

unread,
Jan 18, 2012, 1:37:13 PM1/18/12
to golan...@googlegroups.com
What _would_ be nice however, is if the select statement could use fallthrough and multiple match whatever. Bringing it into line with the functionality of switch.
Eg

select{
case x := <-chanOne, x := <-chanTwo: // I can't see any potential problems with this, have the compiler expand into two duplicate cases
x.bar()
case x := <-myChan: // this one might have compiler lookahead issues, idk about that stuff though
fallthrough
case x := <-myOtherChan
x.foo()
}

to do this now you have to have to either define a helper function, define a closure or duplicate the case code (can get very messy)

si guy

unread,
Jan 18, 2012, 1:42:38 PM1/18/12
to golan...@googlegroups.com
While I'm at it this would be a dream come true

select n := range mySliceOfChans {
case x := <-n:
n.foo()
}

Where mySliceOfChans could be type chan interface{}

Ian Lance Taylor

unread,
Jan 18, 2012, 1:50:26 PM1/18/12
to golan...@googlegroups.com
si guy <sjw...@gmail.com> writes:

Using fallthrough can only work when myChan and myOtherChan have the
same type. Otherwise x would have a different type in the two clauses.
In general this is a fairly special case, and of course you can handle
it in other ways. It's not clear to me that it's worth making the
language more complex for this.

Ian

si guy

unread,
Jan 18, 2012, 1:56:13 PM1/18/12
to golan...@googlegroups.com
Yeah, that's something like I thought. But consider the case when you have multiple worker threads which are not pool-able (for some reason, maybe they are all different) and you want to centralize control of them. I only wonder if a distributed system's code would benefit from some more syntactic sugar in the select statement.

unread,
Jan 18, 2012, 2:36:23 PM1/18/12
to golang-nuts
On Jan 18, 4:18 pm, Aram Hăvărneanu <ara...@mgk.ro> wrote:
> > you should do an average taking into account relative frequency
> > of keyword use, i think.
>
> Or, you can do what I do. Not care :-).

Or you can do the opposite and see that:

1. The theoretical lower bound is 2 (reason: "if", it is recursive)

2. The theoretical upper bound is 9 (reason: "interface", it is
recursive)

3. Because of Go syntax rules, "fallthrough" cannot exist alone and it
isn't recursive. For each "fallthrough", there exists at least one
matching "case", "if", "else", "for". Meaningful Go programs do not
contain recursive endless nesting of blocks (since such recursion has
no semantic value).

4. After giving it some more thought, it can be seen that the
enumeration "case", "if", "else" and "for" (as mentioned in point 3)
is exhaustive. This gives as the following combinations:

case + fallthrough
if + fallthrough
else + fallthrough
for + fallthrough

From these combinations, we can easily see that:

5. The theoretical upper bound for the number of keyword-characters
that a "fallthrough" can add to a meaningful Go program is (4+11)/2 =
7.5. This is because it is possible to meaningfully repeat the
combination "case" + "fallthrough" an infinite number of times.

6. Based on step 5, we can see that the maximum possible number of
keyword characters attributable to a "fallthrough" isn't 11, it is 7.5

... or do not care about any of this and falsely believe that
"fallthrough" accounts for 11 characters ...

andrey mirtchovski

unread,
Jan 18, 2012, 3:19:47 PM1/18/12
to roger peppe, Maxim Pimenov, ⚛, golang-nuts
> you should do an average taking into account relative frequency
> of keyword use, i think.

here are the stats for $GOROOT/src at tip, sorted by frequency:

fallthrough 48
select 52
goto 144
go 196
chan 368
default 576
map 708
defer 778
break 857
continue 996
interface 996
import 1018
const 1054
package 1314
switch 1343
else 1627
range 2287
struct 3554
type 4278
case 4847
var 5055
for 5411
func 14215
return 17457
if 21544

total: 375032 chars in 90723 keywords, avg: 4.133814

a bit hastily written, i'm sorry:

http://play.golang.org/p/00IQuoBwEj

kortschak

unread,
Jan 18, 2012, 3:27:59 PM1/18/12
to golang-nuts
On Jan 18, 10:12 pm, Jan Mercl <jan.me...@nic.cz> wrote:

> You can't alias continue and fallthrough:
>
> package main
>
> func main() {
>         for {
>                 switch {
>                 case 1 > 2:
>                         continue
>                 case 3 < 4:
>                         fallthrough
>                 case 5 > 6:
>                         println("OK")
>                         return
>                 }
>         }
>
> }
>
> Note how continue has completely different effect than fallthrough in the
> above program.

I'm not arguing for the change, but isn't this also a reason why break
can't be used in a switch (even though it is)? If the change were
adopted it would require the use of labels, just as break does. So the
code above would be:

package main

func main() {
L:
for {
switch {
case 1 > 2:
continue L
case 3 < 4:
continue
case 5 > 6:
println("OK")
return
}
}
}

I think this is nasty, but not any worse than the situation with break.

Jan Mercl

unread,
Jan 18, 2012, 3:43:37 PM1/18/12
to golan...@googlegroups.com
On Wednesday, January 18, 2012 9:27:59 PM UTC+1, kortschak wrote:
I'm not arguing for the change, but isn't this also a reason why break
can't be used in a switch (even though it is)? If the change were
adopted it would require the use of labels, just as break does. So the
code above would be:

package main

func main() {
L:
        for {
                switch {
                case 1 > 2:
                        continue L
                case 3 < 4:
                        continue
                case 5 > 6:
                        println("OK")
                        return
                }
        }
}

I think this is nasty, but not any worse than the situation with break.

I agree. In the extreme - every "break", "continue" and "fallthrough" could be removed and (roughly) replaced by the single concept of "goto" ;-)

unread,
Jan 19, 2012, 6:59:27 AM1/19/12
to golang-nuts
On Jan 18, 8:36 pm, ⚛ <0xe2.0x9a.0...@gmail.com> wrote:
> On Jan 18, 4:18 pm, Aram Hăvărneanu <ara...@mgk.ro> wrote:
>
> > > you should do an average taking into account relative frequency
> > > of keyword use, i think.
>
> > Or, you can do what I do. Not care :-).
>
> Or you can do the opposite and see that:
>
> 1. The theoretical lower bound is 2 (reason: "if", it is recursive)
>
> 2. The theoretical upper bound is 9 (reason: "interface", it is
> recursive)
>
> 3. Because of Go syntax rules, "fallthrough" cannot exist alone and it
> isn't recursive. For each "fallthrough", there exists at least one
> matching "case", "if", "else", "for". Meaningful Go programs do not
> contain recursive endless nesting of blocks (since such recursion has
> no semantic value).
>
> 4. After giving it some more thought, it can be seen that the
> enumeration "case", "if", "else" and "for" (as mentioned in point 3)
> is exhaustive. This gives as the following combinations:
>
>   case + fallthrough
>   if + fallthrough
>   else + fallthrough
>   for + fallthrough

I missed one combination:

switch + default + fallthrough

This corrects the upper bound from 7.5 to (6+7+11)/3 = 8.

Shailendra Singh

unread,
Jan 19, 2012, 5:02:35 AM1/19/12
to golan...@googlegroups.com
hindi janta hu.

Carlos C

unread,
Jan 22, 2012, 7:49:59 AM1/22/12
to golang-nuts
> On Jan 18, 1:12 pm, Jan Mercl <jan.me...@nic.cz> wrote:
> You can't alias continue and fallthrough:
>
> [Code]
>
That sir is all that was needed to be said.

Sorry about my premature submission I didn't thought of something like
this.
Reply all
Reply to author
Forward
0 new messages