Improvements to switch

Nick Treleaven nick at geany.org
Fri Apr 19 07:40:34 UTC 2024


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?

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.

>> - 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";
> }
> ```

Yes. In the C++ paper it's `operator is` IIRC.

>> - 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.

Also for your example I don't understand why `goto default` 
wouldn't have the same type as the result for the `default` 
branch.


More information about the dip.ideas mailing list