Improvements to switch
Meta
jared771 at gmail.com
Fri Apr 19 19:27:22 UTC 2024
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:
>> 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:
>>>> - 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";
>>> ```
>>
>> This is already covered by regular switch statements. You can
>> write:
>> ```D
>> case 9, 15 -> "not prime";
>> ```
>
> 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?
I'm not quite sure what you mean - can you illustrate in more
detail?
> 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.
>>> - 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.
>
> 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.
I see. I think having nested case conditions might make it too
complex to understand and maybe even implement.
> 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.
```
More information about the dip.ideas
mailing list