digitalmars.dip.ideas - bool concat patternmatching with switch
- monkyyy (15/15) May 28 ```d
- Dennis (4/7) May 29 Something like that happens in DMD's source with an `X` function:
- monkyyy (3/11) May 29 I really dont understand the compilers code, is `X` exposed to a
- Dennis (9/11) May 29 It's just a normal function, defined right above the switch
- Basile B. (7/15) May 30 It's even a pattern I'd say, there is also this one:
- Salih Dincer (57/65) May 30 Maybe smarter solutions can be produced with BitFlags. At least
- monkyyy (24/89) May 30 your example doesn't show overlapping states and im confused why
- Quirin Schroll (9/17) Jun 04 Two points: You need parens around the case stuff: `case (0,1):`
- monkyyy (4/22) Jun 04 I kinda doubt its a mere enhancment, d has the dumb c style
- Quirin Schroll (15/41) Jun 05 Your `switch` could be:
```d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ``` adding full pattern matching to d seems unlikely to me; but I think something should be done to improve ugly if else chains as d's switch statements are extremely out of date compared to other languages. I propose syntax sugar where if you pass multible bools (and maybe small enums), it will bitshift theses into int and call the same basic asm pattern c used for its switch statements.
May 28
On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:I propose syntax sugar where if you pass multible bools (and maybe small enums), it will bitshift theses into int and call the same basic asm pattern c used for its switch statements.Something like that happens in DMD's source with an `X` function: https://github.com/dlang/dmd/blob/d1f5a7ebd251b3df263a3c6ff87cac4aa9be309c/compiler/src/dmd/e2ir.d#L4770-L4792 You could generalize it up to 64 bits that way.
May 29
On Wednesday, 29 May 2024 at 08:59:10 UTC, Dennis wrote:On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:I really dont understand the compilers code, is `X` exposed to a user ever?I propose syntax sugar where if you pass multible bools (and maybe small enums), it will bitshift theses into int and call the same basic asm pattern c used for its switch statements.Something like that happens in DMD's source with an `X` function: https://github.com/dlang/dmd/blob/d1f5a7ebd251b3df263a3c6ff87cac4aa9be309c/compiler/src/dmd/e2ir.d#L4770-L4792 You could generalize it up to 64 bits that way.
May 29
On Wednesday, 29 May 2024 at 18:41:46 UTC, monkyyy wrote:I really dont understand the compilers code, is `X` exposed to a user ever?It's just a normal function, defined right above the switch statement: ```D static int X(int fty, int tty) { return fty * TMAX + tty; } ``` It combines the two switch variables into a single one with a multiply, the same as your bitshift idea, which is a multiplication by a power of 2.
May 29
On Wednesday, 29 May 2024 at 08:59:10 UTC, Dennis wrote:On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:It's even a pattern I'd say, there is also this one: https://github.com/dlang/dmd/blob/377613993d35e425dfa43a3cc5cfe4c60acb7607/compiler/src/dmd/dtemplate.d#L1078 In my opinion it would be better to have a builtin "set of enum-member" construct and "set of enum-member"-literals, that are switchable (as essentially they are some integer values). Problems arise when the count of members is > 64 tho.I propose syntax sugar where if you pass multible bools (and maybe small enums), it will bitshift theses into int and call the same basic asm pattern c used for its switch statements.Something like that happens in DMD's source with an `X` function: https://github.com/dlang/dmd/blob/d1f5a7ebd251b3df263a3c6ff87cac4aa9be309c/compiler/src/dmd/e2ir.d#L4770-L4792 You could generalize it up to 64 bits that way.
May 30
On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:```d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ```Maybe smarter solutions can be produced with BitFlags. At least it will be more readable... ```d import std.stdio; import std.typecons; enum Status { Idle = 1 << 0, // 0001 Running = 1 << 1, // 0010 Paused = 1 << 2, // 0100 Stopped = 1 << 3 // 1000 } void main() { BitFlags!Status currentStatus; currentStatus = Status.Running; switch (currentStatus) { case Status.Idle: writeln("Durum: Idle"); break; case Status.Running: writeln("Durum: Running"); break; case Status.Paused: writeln("Durum: Paused"); break; case Status.Stopped: writeln("Durum: Stopped"); break; default: writeln("Bilinmeyen durum"); break; } currentStatus = Status.Paused; switch (currentStatus) { case Status.Idle: writeln("Durum: Idle"); break; case Status.Running: writeln("Durum: Running"); break; case Status.Paused: writeln("Durum: Paused"); break; case Status.Stopped: writeln("Durum: Stopped"); break; default: writeln("Bilinmeyen durum"); break; } } ``` SDB 79
May 30
On Thursday, 30 May 2024 at 12:56:40 UTC, Salih Dincer wrote:On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:your example doesn't show overlapping states and im confused why you set up bitshifting without using it switching over an enum I believe is solved with a `with` block; going with the fizz buzz example, an `enum isfizz{true,false}` wouldnt provide clarity do try to take your example as something that show overlaping states ```d ```d nullable(T){ T me; alias me this; bool isnull=false; } bool isvalid(USERNAME);//looks up a string in a database bool authcheck(PASSWORD,USERNAME);//checks if user/pass match switch(status,username.isnull,username.isvalid,password.isnull,password.authcheck(username){ with(Status){ case Running,0,1,0,1://ideal path case ? ,0,1,0,1://reset server case Running,1,?,?,?://show guest account case ? ,?,?,?,0://invalid password page }} ``````d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ```Maybe smarter solutions can be produced with BitFlags. At least it will be more readable... ```d import std.stdio; import std.typecons; enum Status { Idle = 1 << 0, // 0001 Running = 1 << 1, // 0010 Paused = 1 << 2, // 0100 Stopped = 1 << 3 // 1000 } void main() { BitFlags!Status currentStatus; currentStatus = Status.Running; switch (currentStatus) { case Status.Idle: writeln("Durum: Idle"); break; case Status.Running: writeln("Durum: Running"); break; case Status.Paused: writeln("Durum: Paused"); break; case Status.Stopped: writeln("Durum: Stopped"); break; default: writeln("Bilinmeyen durum"); break; } currentStatus = Status.Paused; switch (currentStatus) { case Status.Idle: writeln("Durum: Idle"); break; case Status.Running: writeln("Durum: Running"); break; case Status.Paused: writeln("Durum: Paused"); break; case Status.Stopped: writeln("Durum: Stopped"); break; default: writeln("Bilinmeyen durum"); break; } } ``` SDB 79
May 30
On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:```d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ```Two points: You need parens around the case stuff: `case (0,1):` because `case 0,1:` already exists and means `case 0: case 1:`. I filed an [enhancement issue](https://issues.dlang.org/show_bug.cgi?id=24585) for the basic idea. It’s just a lowering that the front-end can do and doesn’t require a DIP. I guess your idea with the `?` is the only part that needs a DIP. (In your example, one could use `default:` though.)
Jun 04
On Tuesday, 4 June 2024 at 15:55:50 UTC, Quirin Schroll wrote:On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:I kinda doubt its a mere enhancment, d has the dumb c style switches that are thin abstractions of goto; this will require a preprocessing step that im unsure if it exists at all currently```d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ```Two points: You need parens around the case stuff: `case (0,1):` because `case 0,1:` already exists and means `case 0: case 1:`. I filed an [enhancement issue](https://issues.dlang.org/show_bug.cgi?id=24585) for the basic idea. It’s just a lowering that the front-end can do and doesn’t require a DIP. I guess your idea with the `?` is the only part that needs a DIP. (In your example, one could use `default:` though.)
Jun 04
On Tuesday, 4 June 2024 at 20:08:13 UTC, monkyyy wrote:On Tuesday, 4 June 2024 at 15:55:50 UTC, Quirin Schroll wrote:Your `switch` could be: ```d switch (((i%3==0) << 1) | (i%5==0)) { case (1 << 1) | 1: return "fizzbuzz"; case (0 << 1) | 1: return "buzz"; case (1 << 1) | 0: return "fizz"; default: return i.to!string; } ``` The transformation is mechanical and absolutely trivial, and it’s the same “dumb C-style switch” it has always been. For string switching, something more nuanced is needed, but string switches are special anyway.On Tuesday, 28 May 2024 at 19:39:45 UTC, monkyyy wrote:I kinda doubt its a mere enhancment, d has the dumb c style switches that are thin abstractions of goto; this will require a preprocessing step that im unsure if it exists at all currently```d switch(i%3==0,i%5==0){ case 1,1: return "fizzbuzz"; case 0,1: return "buzz"; case 1,0: return "fizz"; case ?,?: return i.to!string; } ```Two points: You need parens around the case stuff: `case (0,1):` because `case 0,1:` already exists and means `case 0: case 1:`. I filed an [enhancement issue](https://issues.dlang.org/show_bug.cgi?id=24585) for the basic idea. It’s just a lowering that the front-end can do and doesn’t require a DIP. I guess your idea with the `?` is the only part that needs a DIP. (In your example, one could use `default:` though.)
Jun 05