V: Simplify the syntax of `switch`

Created on 14 Jul 2019  ·  34Comments  ·  Source: vlang/v

Dear all, how about this simplified syntax of switch?

Current syntax mentioned in doc:

switch os {
    case 'darwin': println('macOS.')
    case 'linux': println('Linux.')
    default: println(os) 
}

Suggested one (close to Rust, but even less typing):

switch os {
    ‘darwin’: println(‘macOS’)
    ‘linux’: println(‘Linux’)
    _: println(os)
}

Seems Alex wants to replace switch by match, but the syntax can be the same.

No more case keyword here.

Benefit: Less typing, and good readability.

When you see switch, you have an intuition that there will be some cases following - because this's what switch used for, each case is clear with the : symbol.

Replace default identifier by _

Benefit: Less typing, better readability.

It uses identifier _ here to catch all rest cases.

_ means __anonymous variable__ or __anything but i don't care__. It is widely used and accepted in Go, Rust, Erlang, Python. Maybe more, especially in functional programming languages.

References:

Compare this suggested syntax with some languages:

Go

Go has same syntax as the one in vlang doc:

switch os {
    case 'darwin': println('macOS.')
    case 'linux': println('Linux.')
    default: println(os) 
}

Rust

match os {
    "darwin" => println!("Darwin."),
    "linux" => println!("Linux."),
    _ => println!(os)
}

: has (2 chars) less typing than =>.

Erlang

%% variable in Erlang must start with a uppercase.
%% e.g. both `Os` and `OS` are ok, but not `os` (this is an atom)
case OS of
    "darwin" -> io:format("Darwin~n"),
    "linux" -> io:format("Linux~n"),
    _ -> io:format("~p~n", OS)
end.

Python

Python doesn't have switch/case, have to use if-else instead.

Feature Request

Most helpful comment

switch will be replaced with match expressions:

s := match x {
    1 => println('returning one')
         'one'
    2 => 'two'
    3, 4 => 'three or four'
    else => '?'
}

All 34 comments

I love the idea of V language. do one thing in one way.

@lcddh I don’t get your point.

My suggestion is simplifying an existing syntax, not introduce a new syntax. No conflict with the “do one thing in one way” rule.

Wrong, it doesn't make it simple, rather makes it complex to remember the proper syntax. For example in the current syntax:

switch os {
    case 'darwin': println('macOS.')
    case 'linux': println('Linux.')
    default: println(os) 
}

Straight forward, better readability, doesn't require the knowledge of knowing about conventions. Compared to this:

switch os {
    ‘darwin’: println(‘macOS’)
    ‘linux’: println(‘Linux’)
    _: println(os)
}

Less readability, the user needs to know the convention of using _ identifier. The user might also forget the syntax since for the default case, there is no keyword to remember.
Besides, this is a very critical syntax change which I think goes against the vlang's philosophy of

The things you can learn from documentation today are going to stay the same.

kicking out keywords from the existing syntax is not simplifying

V is still in alpha stage, if something is not good enough, we still have time to make it right. insisting in “stay the same” at this stage is wrong.

It is already good. Readability does matter. Having two or three less chars at the cost of readability is bad design decision.

This issue is just a suggestion, I suggested this because I think the readability is better (to me, and probably to others). it waits for people especially creator Alex’s comments, and it’s all Alex’s decision.

Something good to me doesn’t mean good to you, and the vice verse.

Tell you what, you need to tell creator Alex don’t change syntax too and “stay the same” :) https://github.com/vlang/v/issues/1131

My point is simple: make it right when we still have time. Alex fixes things he thought which was not good enough.

I agree. My view is mine and the ultimate decision is Alex's.

I would strongly welcome any syntax that allows several 'cases' referring to the same expression. C has it:

...
case 1:
case 2:
case 3:
    some_expression;
    break;
case 4:
    another_expression;
    break;
...

I would strongly welcome any syntax that allows several 'cases' referring to the same expression. C has it:

It already does:

case 1,2,3:

switch will be replaced with match expressions:

s := match x {
    1 => println('returning one')
         'one'
    2 => 'two'
    3, 4 => 'three or four'
    else => '?'
}

Besides, this is a very critical syntax change which I think goes against the vlang's philosophy of

The docs on the switch statement have always had TODO: replace with match.

How about replace => by :?

1 => 'one'

Will this support statement blocks?

Yes, without {}.

How about replace => by :?

=> is easier for the parser and the user, since there will be no {} for statement blocks.

so if we need to have blocks of logic we have to use if else?
edit: I just read the comments. But will that mean you need to return a value from the block?

OCaml

match os with
  "darwin" -> print_endline("macOS.")
| "linux" -> print_endline("Linux.")
| _ -> print_endline(os)

you can also have fallthrough

match os with
  "darwin"
| "linux" -> print_endline("Linux.")
| _ -> print_endline(os)

but even more like deconstruct variant like in rust (and in new csharp)

Pascal

case ord(c) of
    // empty statement, so the control characters are not
    // considered by the else-branch as non-ASCII-characters
    0..$1F, $7F: ;
    $20..$7E:
    begin
        writeLn('You entered an ASCII printable character.');
    end;
    else
    begin
        writeLn('You entered a non-ASCII character.');
    end;
end;

I want to add match while keeping switch.sometimes, multiple choices are always good.thx.

@fenginsc Exactly:

switch will be replaced with match expressions:

It is useful to be able to do things in the case block, which wouldn't be possible with match expressions, it appears (as per @medvednikov's example above).

@elimisteve

what do you have in mind? Perhaps it's possible.

Having multiple options is allowed:

s := match x {
    1 => println('returning one')
         'one'
    2 => 'two'
    3, 4 => 'three or four'
    else => '?'
}

@joe-conigliaro

so if we need to have blocks of logic we have to use if else?
edit: I just read the comments. But will that mean you need to return a value from the block?

No, you don't need to return a value.

What do you mean by blocks of logic?

@medvednikov I just mean will we be able to use match like a switch?

match x {
    1 => do_something()
    2 => 
         // block of code
         if something {
             do_something_else()
         }
    else => do_default()
}

Yes, see the example above :)

@medvednikov Cool I thought maybe it had to return a value :)

They will work like if expressions. You can return an expression, or you can use it as a statement.

@medvednikov Oooh, I see... Sounds great to me.

@medvednikov fantastic!

The new match statement is live. It can't return a value yet.

https://github.com/vlang/v/blob/master/compiler/tests/match_test.v

“:” is better. :( (“=“ in top-right corner on keyboard, “>” in bottom-right corner.)

@iredmail But then a match block would look like a struct/object -- too much, perhaps.

We discussed about alias module before, and Alex mentioned he prefers similar syntax like this:

type myint int
import alias module

But i strongly recommended to use import module as alias, and Alex raised a vote on Twitter, most people (about 80%+) prefer the import module as alias syntax and Alex eventually switched to that.

I think similar syntax is NOT a bad thing, easy to remember. The point is whether the syntax itself is clear enough. btw:

Struct

struct Color {
        r int
        g int
        b int
}

Match

match color {
    r: ...
   g: ...
   b: ...
}

I think @elimisteve was referring to struct initialization:

match color {
   r: ...
   g: ...
   b: ...
}

```
Color {
r: ...
g: ...
b: ...
}

Close this issue since we already have a new match syntax: https://vlang.io/docs#match

Was this page helpful?
0 / 5 - 0 ratings

Related issues

radare picture radare  ·  3Comments

jtkirkpatrick picture jtkirkpatrick  ·  3Comments

cjmxp picture cjmxp  ·  3Comments

XVilka picture XVilka  ·  3Comments

clpo13 picture clpo13  ·  3Comments