digitalmars.dip.ideas - Improvements to switch
- ryuukk_ (23/23) Apr 16 It is time to make them nice to use
- Basile B. (13/20) Apr 16 About this, the main point is rather
- IchorDev (10/18) Apr 27 You can already do that.
- Basile B. (8/28) Apr 27 Sure but the matching AST is unnecessarily complex. A function
- =?UTF-8?B?Q2hsb8Op?= (31/61) Apr 28 Specifically promoting switch to an expression would be a wasted
- Basile B. (28/48) Apr 30 Besides the problems exposed in the first answer (essentially:
- Nick Treleaven (4/7) May 01 That's why the syntax should be designed to be easily
- Meta (44/67) Apr 16 A couple more things:
- Nick Treleaven (30/40) Apr 17 Presumably we could leave off the type:
- Nick Treleaven (23/25) Apr 17 Some other things, based on section 3.3 of this C++ proposal:
- Meta (27/52) Apr 18 This is already covered by regular switch statements. You can
- Nick Treleaven (19/77) Apr 19 It would be ambiguous to write e.g. `case name if (cond) ->` - is
- Meta (25/86) Apr 19 I'm not quite sure what you mean - can you illustrate in more
- Nick Treleaven (25/113) Apr 23 Where you had:
- ShowMeTheWay (14/23) Apr 24 the 'switch' keyword implies old-school.. D needs a new term.
- Walter Bright (7/7) Apr 22 I've thought about it for a while now. Improving switch has a lot of iss...
- Richard (Rikki) Andrew Cattermole (8/20) Apr 22 I was really looking forward to your recent DConf Online talk about
- Walter Bright (3/12) Apr 22 Sumtypes must come before pattern matching. I had a proposal for it:
- ShowMeTheWay (10/20) Apr 23 int x = 1;
- ShowMeTheWay (3/26) Apr 23 aka ..a new language construct (i.e. an improvement over a switch
- Quirin Schroll (3/13) Apr 25 Why not do it as C# does and put `switch` after the expression?
- Dukc (18/22) Apr 24 I'm certainly open to exploring the general notion. I think
It is time to make them nice to use - allow them as expression ```D int myvalue = switch(code) { // ... }; ``` - more concise ```D switch(code) { case 1 -> "what"; case 2, 3 -> "ok"; else -> "no"; } ``` - pattern match ```D switch(tagged) { case A, B -> do_that(); case C myc -> do_this(myc); else -> nothing(); } ```
Apr 16
On Tuesday, 16 April 2024 at 10:34:21 UTC, ryuukk_ wrote:It is time to make them nice to use - allow them as expression ```D int myvalue = switch(code) { // ... }; ```About this, the main point is rather ```d /*-->*/ const /*<--*/ int myvalue = switch(code) { // ... }; ``` "ah finally you can define a const var decl that relies on branching" (without using the conditional expression...) Then there's something you must think about, that's the fallback, i.e the default clause. If you use the default clause to error you're lucky because D has noreturn now.
Apr 16
On Tuesday, 16 April 2024 at 16:00:48 UTC, Basile B. wrote:About this, the main point is rather ```d /*-->*/ const /*<--*/ int myvalue = switch(code) { // ... }; ``` "ah finally you can define a const var decl that relies on branching" (without using the conditional expression...)You can already do that. ```d const string myValue = (){ switch(code){ case 1: return "what"; case 2, 3: return "ok"; default: return "no"; } }();
Apr 27
On Saturday, 27 April 2024 at 14:58:19 UTC, IchorDev wrote:On Tuesday, 16 April 2024 at 16:00:48 UTC, Basile B. wrote:Sure but the matching AST is unnecessarily complex. A function literal, plenty of return statements, at least 1 capture. Consequently the path borrowed by the compiler is much more complex, it has to do things that would not be done with the expression: return type inference, block exits, etc. Then without optimizations enabled that does not have the equivalent runtime performances.About this, the main point is rather ```d /*-->*/ const /*<--*/ int myvalue = switch(code) { // ... }; ``` "ah finally you can define a const var decl that relies on branching" (without using the conditional expression...)You can already do that. ```d const string myValue = (){ switch(code){ case 1: return "what"; case 2, 3: return "ok"; default: return "no"; } }();
Apr 27
On 4/28/24 01:58, Basile B. wrote:On Saturday, 27 April 2024 at 14:58:19 UTC, IchorDev wrote:Specifically promoting switch to an expression would be a wasted opportunity to generalize this to other types of statements, such as try statements. Here are some examples in pseudo-D of how that could be useful. In these examples, a hypothetical do keyword could prefix any statement and turn it into an expression, and a yield statement would provide the result of evaluating that expression: // no need to (default-)initialize file first auto file = do try { yield open(path); } catch (ErrnoException ex) { if (ex.errno == ENOENT) return; // return from caller throw ex; }; // use file without catching ErrnoException file.write("hello"); Or foreach statements: const value = do { foreach (item; someOpApplyStruct) if (f(item)) yield item; throw new NotFoundError; }; If the do-ed statement would run off the end (as with a non-void function lacking a return statement) that would be an error. Besides initializing variables, another advantage of promoting statements to expressions directly instead of through a called lambda is that you can have control flow out of the expression into another statement, such as by break, continue, or return statements.On Tuesday, 16 April 2024 at 16:00:48 UTC, Basile B. wrote:Sure but the matching AST is unnecessarily complex. A function literal, plenty of return statements, at least 1 capture. Consequently the path borrowed by the compiler is much more complex, it has to do things that would not be done with the expression: return type inference, block exits, etc. Then without optimizations enabled that does not have the equivalent runtime performances.About this, the main point is rather ```d /*-->*/ const /*<--*/ int myvalue = switch(code) { // ... }; ``` "ah finally you can define a const var decl that relies on branching" (without using the conditional expression...)You can already do that. ```d const string myValue = (){ switch(code){ case 1: return "what"; case 2, 3: return "ok"; default: return "no"; } }();
Apr 28
On Saturday, 27 April 2024 at 14:58:19 UTC, IchorDev wrote:On Tuesday, 16 April 2024 at 16:00:48 UTC, Basile B. wrote:Besides the problems exposed in the first answer (essentially: "it's a workaround") I've found a case where this does not work. It's about selecting an lvalue with a switch: ```d void main() { int a,b,c,d,cond; auto ref () { switch (cond) { case 1: return a; case 2: return b; case 3: return c; default: return d; } }() = 0; } ``` see https://issues.dlang.org/show_bug.cgi?id=24525 The switchexp would have the same problem: the parser sees "switch" then it branches on statement parsing. Statement parsing sees "switch", then it branches on SwitchStmt parsing. Not so dramatic but the lambda solution is 1. a workaround, 2. not perfect. For that case you have 1. to explain the lambda trick 2. why you have to put the lambda between parens. With the switch expr, you just have to explain point 2.About this, the main point is rather ```d /*-->*/ const /*<--*/ int myvalue = switch(code) { // ... }; ``` "ah finally you can define a const var decl that relies on branching" (without using the conditional expression...)You can already do that. ```d const string myValue = (){ switch(code){ case 1: return "what"; case 2, 3: return "ok"; default: return "no"; } }();
Apr 30
On Tuesday, 30 April 2024 at 13:15:45 UTC, Basile B. wrote:see https://issues.dlang.org/show_bug.cgi?id=24525There's now a fix for that.The switchexp would have the same problem: the parser sees "switch" then it branches on statement parsing.That's why the syntax should be designed to be easily distinguishable by the parser.
May 01
On Tuesday, 16 April 2024 at 10:34:21 UTC, ryuukk_ wrote:It is time to make them nice to use - allow them as expression ```D int myvalue = switch(code) { // ... }; ``` - more concise ```D switch(code) { case 1 -> "what"; case 2, 3 -> "ok"; else -> "no"; } ``` - pattern match ```D switch(tagged) { case A, B -> do_that(); case C myc -> do_this(myc); else -> nothing(); } ```A couple more things: - branch guards ```D auto input = readln().strip().to!int(); auto s = switch (input) { case n if (n == 0) -> "zero"; case n if (n > 0) -> "greater than zero"; case n if (n < 0) -> "less than zero"; }; switch (readln().strip()) { case string: "" -> writeln("empty string"); // Naming the value is optional case string s: "asdf" -> writeln(s[2..$]); // Prints "df" } ``` - pattern match on arrays, slices: ```D int[3] staticArr = [1, 2, 3]; switch (staticArr) { case int[N], size_t N -> writeln("Static int array of size ", N); case int[N], size_t N: 1 -> writeln("This branch won't be taken"); case int[N], size_t N if (N == 1) -> writeln("Equivalent to previous branch"); case int[2] -> writeln("This branch won't be taken either"); case string[N], N -> writeln("Nope"); } string[] slice = ["D", "rocks", "!"]; switch (slice) { case string[] : [] -> writeln("empty slice"); case string[] s: ["D"] -> writln(s[0]); case string[] s: ["D", rest...] -> writeln(rest); // Prints ["rocks", "!"] case string[] s: ["D", mid..., "!"] -> writeln(mid); // Prints "rocks" case string[] s: ["D", "rocks", "!"] -> writeln(s); // Prints ["D", "rocks", "!"] } ``` It'd be really nice to be able to pattern match on ranges as well, but I don't know exactly how we'd do that given how they work.
Apr 16
On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:case string: "" -> writeln("empty string"); // Naming the value is optionalPresumably we could leave off the type: ```d case : "" -> writeln("empty string"); ``` Though we might want to require an identifier or `_` when there is a type. So we'd have this grammar: ``` Case: case Pattern -> Statement case Type? Identifier Pattern? -> Statement Pattern: `:` AssignExpression `if` `(` AssignExpression `)` ```int[3] staticArr = [1, 2, 3]; switch (staticArr) { case int[N], size_t N -> writeln("Static int array of size ", N);Could have type inference too, like for template parameter inference. ```d case T[N] _, T, alias N -> writeln("Static ", T.stringof, " array of size ", N); ``` Inferred symbols would be listed after matching values.case string[] s: ["D", rest...] -> writeln(rest); // Prints ["rocks", "!"]So `rest` would be typed `string[]`.case string[] s: ["D", mid..., "!"] -> writeln(mid); // Prints "rocks"I think `mid` cannot be variadic in order for it to be typed `string`. So it would be: ```d case string[] s: ["D", mid, "!"] -> writeln(mid); // Prints "rocks" ```
Apr 17
On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:- branch guards - pattern match on arrays, slices:Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ``` - Multiple constraints required for a result: && E.g. ```d switch (variant) { case int _ && :42 -> "int and 42"; ``` - Grouping common names and constraints: { } E.g. ```d switch (variant) { case int i { case if (i < 0) -> "negative int"; default -> "some other int"; } ```
Apr 17
On Wednesday, 17 April 2024 at 11:24:16 UTC, Nick Treleaven wrote:On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:This is already covered by regular switch statements. You can write: ```D case 9, 15 -> "not prime"; ```- branch guards - pattern match on arrays, slices:Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ```- Multiple constraints required for a result: && E.g. ```d switch (variant) { case int _ && :42 -> "int and 42"; ```I think this would require some sort of `opMatch` function to allow custom unpacking of arbitrary structs/classes. Ideally it would allow you to do: ```D switch (variant) { case int n if (n == 42) -> "int and 42"; // Or alternatively case int n: 42 -> "int and 42"; } ```- Grouping common names and constraints: { } E.g. ```d switch (variant) { case int i { case if (i < 0) -> "negative int"; default -> "some other int"; } ``````D switch (variant) { // goto default is already a feature of regular switch statements case int i -> i < 0 ? "negative int" : goto default; default -> "some other int"; } ``` This will work _if_ `goto default` is typed as `noreturn`. I doubt that's the case, but that's something that can also be fixed in the compiler.
Apr 18
On Friday, 19 April 2024 at 06:28:55 UTC, Meta wrote:On Wednesday, 17 April 2024 at 11:24:16 UTC, Nick Treleaven wrote:It would be ambiguous to write e.g. `case name if (cond) ->` - is it matching a value `name`, or is `name` naming the switch variable? But the grammar was me trying to extrapolate from your examples, and it might not be workable for that to be compatible with today's switch statement. Perhaps it's better to not reuse `switch` because we will want pattern matching with multiple statement branches, we won't always want `switch` to be an expression.On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:This is already covered by regular switch statements. You can write: ```D case 9, 15 -> "not prime"; ```- branch guards - pattern match on arrays, slices:Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ```Yes. In the C++ paper it's `operator is` IIRC.- Multiple constraints required for a result: && E.g. ```d switch (variant) { case int _ && :42 -> "int and 42"; ```I think this would require some sort of `opMatch` function to allow custom unpacking of arbitrary structs/classes. Ideally it would allow you to do: ```D switch (variant) { case int n if (n == 42) -> "int and 42"; // Or alternatively case int n: 42 -> "int and 42"; } ```BTW that's not what my example does - the `i < 0` is part of the matching, not part of the result. The difference is there can be other `case` statements under the first one. `case if (i < 0) ->` would try the next case statement when i >= 0 rather than jumping to the default case. Also for your example I don't understand why `goto default` wouldn't have the same type as the result for the `default` branch.- Grouping common names and constraints: { } E.g. ```d switch (variant) { case int i { case if (i < 0) -> "negative int"; default -> "some other int"; } ``````D switch (variant) { // goto default is already a feature of regular switch statements case int i -> i < 0 ? "negative int" : goto default; default -> "some other int"; } ``` This will work _if_ `goto default` is typed as `noreturn`. I doubt that's the case, but that's something that can also be fixed in the compiler.
Apr 19
On Friday, 19 April 2024 at 07:40:34 UTC, Nick Treleaven wrote:On Friday, 19 April 2024 at 06:28:55 UTC, Meta wrote:I'm not quite sure what you mean - can you illustrate in more detail?On Wednesday, 17 April 2024 at 11:24:16 UTC, Nick Treleaven wrote:It would be ambiguous to write e.g. `case name if (cond) ->` - is it matching a value `name`, or is `name` naming the switch variable?On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:This is already covered by regular switch statements. You can write: ```D case 9, 15 -> "not prime"; ```- branch guards - pattern match on arrays, slices:Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ```But the grammar was me trying to extrapolate from your examples, and it might not be workable for that to be compatible with today's switch statement. Perhaps it's better to not reuse `switch` because we will want pattern matching with multiple statement branches, we won't always want `switch` to be an expression.Yeah maybe not. That was just some mock syntax off the top of my head, and it's probably not suitable for extracting a formal grammar.I see. I think having nested case conditions might make it too complex to understand and maybe even implement.BTW that's not what my example does - the `i < 0` is part of the matching, not part of the result. The difference is there can be other `case` statements under the first one. `case if (i < 0) ->` would try the next case statement when i >= 0 rather than jumping to the default case.- Grouping common names and constraints: { } E.g. ```d switch (variant) { case int i { case if (i < 0) -> "negative int"; default -> "some other int"; } ``````D switch (variant) { // goto default is already a feature of regular switch statements case int i -> i < 0 ? "negative int" : goto default; default -> "some other int"; } ``` This will work _if_ `goto default` is typed as `noreturn`. I doubt that's the case, but that's something that can also be fixed in the compiler.Also for your example I don't understand why `goto default` wouldn't have the same type as the result for the `default` branch.Conceptually, `goto default` and other constructs that transfer execution to a different part of the code should be typed as `noreturn`, because then you can do stuff like: ```D auto input = readln() || throw new Exception("empty input"); ``` Although in this case it would actually be pretty weird... I _think_ it would enable this type of code: ```D Variant v = 10; auto str = switch (variant) { case int i -> i < 0 ? "negative int" : goto default; default -> writeln("invalid value"); }; // The only sane type for `str` is `noreturn`, and thus it should crash the program if we try to read from it. ```
Apr 19
On Friday, 19 April 2024 at 19:27:22 UTC, Meta wrote:On Friday, 19 April 2024 at 07:40:34 UTC, Nick Treleaven wrote:Where you had: ```d auto s = switch (input) { case n if (n == 0) -> "zero"; case n if (n > 0) -> "greater than zero"; case n if (n < 0) -> "less than zero"; ``` I understand that in the last case, it's giving input an alternative name n, then testing n < 0. But suppose n is already a symbol in scope, and the test might not involve n: case n if (p < 0) I might expect that to match when input is equal to the value of n and p is negative. But how does the parser know if n is supposed to be an alternative name for input, or to be a value looked up in the current scope. It can be figured out at semantic time, but I think it would be better to design the syntax to be unambiguous at the parser stage about whether it is introducing a new symbol or not.On Friday, 19 April 2024 at 06:28:55 UTC, Meta wrote:I'm not quite sure what you mean - can you illustrate in more detail?On Wednesday, 17 April 2024 at 11:24:16 UTC, Nick Treleaven wrote:It would be ambiguous to write e.g. `case name if (cond) ->` - is it matching a value `name`, or is `name` naming the switch variable?On Tuesday, 16 April 2024 at 18:25:45 UTC, Meta wrote:This is already covered by regular switch statements. You can write: ```D case 9, 15 -> "not prime"; ```- branch guards - pattern match on arrays, slices:Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ```I think it would be straightforward, but indeed could wait until later.But the grammar was me trying to extrapolate from your examples, and it might not be workable for that to be compatible with today's switch statement. Perhaps it's better to not reuse `switch` because we will want pattern matching with multiple statement branches, we won't always want `switch` to be an expression.Yeah maybe not. That was just some mock syntax off the top of my head, and it's probably not suitable for extracting a formal grammar.I see. I think having nested case conditions might make it too complex to understand and maybe even implement.BTW that's not what my example does - the `i < 0` is part of the matching, not part of the result. The difference is there can be other `case` statements under the first one. `case if (i < 0) ->` would try the next case statement when i >= 0 rather than jumping to the default case.- Grouping common names and constraints: { } E.g. ```d switch (variant) { case int i { case if (i < 0) -> "negative int"; default -> "some other int"; } ``````D switch (variant) { // goto default is already a feature of regular switch statements case int i -> i < 0 ? "negative int" : goto default; default -> "some other int"; } ``` This will work _if_ `goto default` is typed as `noreturn`. I doubt that's the case, but that's something that can also be fixed in the compiler.I would expect the default case to produce a value unless it does not terminate. So I would require writing an assert(0) at the end of it.Also for your example I don't understand why `goto default` wouldn't have the same type as the result for the `default` branch.Conceptually, `goto default` and other constructs that transfer execution to a different part of the code should be typed as `noreturn`, because then you can do stuff like: ```D auto input = readln() || throw new Exception("empty input"); ``` Although in this case it would actually be pretty weird... I _think_ it would enable this type of code: ```D Variant v = 10; auto str = switch (variant) { case int i -> i < 0 ? "negative int" : goto default; default -> writeln("invalid value"); }; // The only sane type for `str` is `noreturn`, and thus it should crash the program if we try to read from it. ```
Apr 23
On Wednesday, 17 April 2024 at 11:24:16 UTC, Nick Treleaven wrote:... Some other things, based on section 3.3 of this C++ proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2392r2.pdf - Multiple alternatives that have the same result: || E.g. ```d case :9 || :15 -> "not prime"; ``` ...`the 'switch' keyword implies old-school.. D needs a new term. and the 'case' word is superfluous. something like this perhaps: int x = 15; check x { < 0 _ => writeln!("Sorry. That's not even possible!"), 0 | 1 => writeln!("wtf!"), 2..5 => writeln!("mmm.. not too bad"), 6..10 => writeln!("that's a bit better"), 11..15 => writeln!("now you're getting it"), 20 | >20 => writeln!("Wow! I think you've got it now"), _ => writeln!("Oops! Something's not right."), }
Apr 24
I've thought about it for a while now. Improving switch has a lot of issues with it, such as the unusual scoping rules, the ability to goto in and out of it, the ability to interleave switch/case with other looping constructs (!). It's unsalvageable. It's better to create a new construct, let's say "match", and design an unconstrained syntax for it to accommodate pattern matching in particular. ("match" is already an identifier in common use, some other name would be better.)
Apr 22
On 23/04/2024 4:45 AM, Walter Bright wrote:I've thought about it for a while now. Improving switch has a lot of issues with it, such as the unusual scoping rules, the ability to goto in and out of it, the ability to interleave switch/case with other looping constructs (!). It's unsalvageable. It's better to create a new construct, let's say "match", and design an unconstrained syntax for it to accommodate pattern matching in particular. ("match" is already an identifier in common use, some other name would be better.)I was really looking forward to your recent DConf Online talk about matching. It is why I have avoided this idea up until now, I wanted to see what you have come up with. Same thing for sum types. If you have any design work on this subject, I think other people not just myself would be interested in having a read.
Apr 22
On 4/22/2024 10:33 AM, Richard (Rikki) Andrew Cattermole wrote:I was really looking forward to your recent DConf Online talk about matching. It is why I have avoided this idea up until now, I wanted to see what you have come up with. Same thing for sum types. If you have any design work on this subject, I think other people not just myself would be interested in having a read.Sumtypes must come before pattern matching. I had a proposal for it: https://www.digitalmars.com/d/archives/digitalmars/D/sumtypes_for_D_366242.html
Apr 22
On Monday, 22 April 2024 at 16:45:35 UTC, Walter Bright wrote:I've thought about it for a while now. Improving switch has a lot of issues with it, such as the unusual scoping rules, the ability to goto in and out of it, the ability to interleave switch/case with other looping constructs (!). It's unsalvageable. It's better to create a new construct, let's say "match", and design an unconstrained syntax for it to accommodate pattern matching in particular. ("match" is already an identifier in common use, some other name would be better.)int x = 1; check x { 1 => writeln!("one"), 2 => writeln!("two"), 3 => writeln!("three"), 4 => writeln!("four"), 5 => writeln!("five"), _ => writeln!("something else"), }
Apr 23
On Wednesday, 24 April 2024 at 06:52:51 UTC, ShowMeTheWay wrote:On Monday, 22 April 2024 at 16:45:35 UTC, Walter Bright wrote:aka ..a new language construct (i.e. an improvement over a switch expression) called 'a check expression'.I've thought about it for a while now. Improving switch has a lot of issues with it, such as the unusual scoping rules, the ability to goto in and out of it, the ability to interleave switch/case with other looping constructs (!). It's unsalvageable. It's better to create a new construct, let's say "match", and design an unconstrained syntax for it to accommodate pattern matching in particular. ("match" is already an identifier in common use, some other name would be better.)int x = 1; check x { 1 => writeln!("one"), 2 => writeln!("two"), 3 => writeln!("three"), 4 => writeln!("four"), 5 => writeln!("five"), _ => writeln!("something else"), }
Apr 23
On Monday, 22 April 2024 at 16:45:35 UTC, Walter Bright wrote:I've thought about it for a while now. Improving switch has a lot of issues with it, such as the unusual scoping rules, the ability to goto in and out of it, the ability to interleave switch/case with other looping constructs (!). It's unsalvageable. It's better to create a new construct, let's say "match", and design an unconstrained syntax for it to accommodate pattern matching in particular. ("match" is already an identifier in common use, some other name would be better.)There, it’s something like `string[1..$-1] switch { … }`.
Apr 25
On Tuesday, 16 April 2024 at 10:34:21 UTC, ryuukk_ wrote:It is time to make them nice to use - allow them as expression - more concise - pattern matchI'm certainly open to exploring the general notion. I think Walter is too, at least regarding the last one, as I recall he has said somewhere that D will have pattern matching. However, whether we actually want to change `switch` depends on the details, exactly how are we going to do it? Every new langauge feature has to consider added language complexity, corner cases and backwards compatibility questions. How hard those are to deal with, compared to the benefit, is the ultimate test of worth for the feature. I somewhat tend to agree with Walter. `switch` works how it works thanks to C heritage, as a result it has a lot of backwards compatibility burden. Any attempt to overhaul it to support pattern matching as a primary use case is probably going to complicate the language more than just designing a new construct. But I'm not locked to this position - if someone presents a clever `switch` upgrade proposal along with the details, I'd be happy to be proven wrong.
Apr 24