digitalmars.D - Type deduction using switch case
- Xinok (30/30) Feb 18 2012 While reading "The Right Approach to Exceptions", it gave me this
- Robert Jacques (4/34) Feb 18 2012 You can do this today using a string switch:
- Xinok (6/32) Feb 18 2012 Notice how it's "int i" and not just "int". Also notice how each
- Robert Jacques (14/48) Feb 18 2012 And why not simply do:
- Xinok (4/26) Feb 19 2012 Because all of the code gets compiled in, so if one statement
- Nick Sabalausky (15/43) Feb 18 2012 Yea, pattern matching, basically. Great as D is, pattern matching is one...
- David (3/13) Feb 19 2012 +1 best would be with built-in Tuples, but I guess built-in tuples are
While reading "The Right Approach to Exceptions", it gave me this idea. The user would declare a list of variables of different types as case statements, and the variable with matches the type of the switch expression is used. I don't know how the syntax should look, this is merely an example: void foo(T)(T arg){ switch(arg){ case int i: writeln("Type is int ", i); break; case float f: writeln("Type is float ", f); break; case string s: writeln("Type is string ", s); break; default: writeln("Type is unknown"); break; } } While static if would be more practical for templates, my idea could be extended to dynamic upcasting of classes as well, which could be applied to exception handling: try{ ... } catch(Throwable err) switch(err){ case IOError a: break; case OutOfMemoryError b: break; default: throw err; }
Feb 18 2012
On Sat, 18 Feb 2012 18:33:01 -0600, Xinok <xinok live.com> wrote:While reading "The Right Approach to Exceptions", it gave me this idea. The user would declare a list of variables of different types as case statements, and the variable with matches the type of the switch expression is used. I don't know how the syntax should look, this is merely an example: void foo(T)(T arg){ switch(arg){ case int i: writeln("Type is int ", i); break; case float f: writeln("Type is float ", f); break; case string s: writeln("Type is string ", s); break; default: writeln("Type is unknown"); break; } }The above should be switch (T) not switch(arg) for the example to be correct.While static if would be more practical for templates, my idea could be extended to dynamic upcasting of classes as well, which could be applied to exception handling: try{ ... } catch(Throwable err) switch(err){ case IOError a: break; case OutOfMemoryError b: break; default: throw err; }You can do this today using a string switch: switch(err.classinfo.name) { ... }
Feb 18 2012
On Sunday, 19 February 2012 at 00:49:56 UTC, Robert Jacques wrote:On Sat, 18 Feb 2012 18:33:01 -0600, Xinok <xinok live.com> wrote:Notice how it's "int i" and not just "int". Also notice how each writeln statement also prints the variable. Each case statement declares a variable, so it matches the type of the expression against the type of the variable, and stores the switch expression in that variable.While reading "The Right Approach to Exceptions", it gave me this idea. The user would declare a list of variables of different types as case statements, and the variable with matches the type of the switch expression is used. I don't know how the syntax should look, this is merely an example: void foo(T)(T arg){ switch(arg){ case int i: writeln("Type is int ", i); break; case float f: writeln("Type is float ", f); break; case string s: writeln("Type is string ", s); break; default: writeln("Type is unknown"); break; } }The above should be switch (T) not switch(arg) for the example to be correct.
Feb 18 2012
On Sat, 18 Feb 2012 20:03:51 -0600, Xinok <xinok live.com> wrote:On Sunday, 19 February 2012 at 00:49:56 UTC, Robert Jacques wrote:And why not simply do: void foo(T)(T arg){ switch(T){ case int: writeln("Type is int ", arg); break; case float: writeln("Type is float ", arg); break; case string: writeln("Type is string ", arg); break; default: writeln("Type is unknown"); break; } }On Sat, 18 Feb 2012 18:33:01 -0600, Xinok <xinok live.com> wrote:Notice how it's "int i" and not just "int". Also notice how each writeln statement also prints the variable. Each case statement declares a variable, so it matches the type of the expression against the type of the variable, and stores the switch expression in that variable.While reading "The Right Approach to Exceptions", it gave me this idea. The user would declare a list of variables of different types as case statements, and the variable with matches the type of the switch expression is used. I don't know how the syntax should look, this is merely an example: void foo(T)(T arg){ switch(arg){ case int i: writeln("Type is int ", i); break; case float f: writeln("Type is float ", f); break; case string s: writeln("Type is string ", s); break; default: writeln("Type is unknown"); break; } }The above should be switch (T) not switch(arg) for the example to be correct.
Feb 18 2012
On Sunday, 19 February 2012 at 06:28:37 UTC, Robert Jacques wrote:On Sat, 18 Feb 2012 20:03:51 -0600, Xinok <xinok live.com> wrote:Because all of the code gets compiled in, so if one statement uses the type incorrectly, it won't compile. It also doesn't allow for dynamic upcasting of classes as in my second example.Notice how it's "int i" and not just "int". Also notice how each writeln statement also prints the variable. Each case statement declares a variable, so it matches the type of the expression against the type of the variable, and stores the switch expression in that variable.And why not simply do: void foo(T)(T arg){ switch(T){ case int: writeln("Type is int ", arg); break; case float: writeln("Type is float ", arg); break; case string: writeln("Type is string ", arg); break; default: writeln("Type is unknown"); break; } }
Feb 19 2012
"Xinok" <xinok live.com> wrote in message news:yeuigezlevjbhgufwrti forum.dlang.org...While reading "The Right Approach to Exceptions", it gave me this idea. The user would declare a list of variables of different types as case statements, and the variable with matches the type of the switch expression is used. I don't know how the syntax should look, this is merely an example: void foo(T)(T arg){ switch(arg){ case int i: writeln("Type is int ", i); break; case float f: writeln("Type is float ", f); break; case string s: writeln("Type is string ", s); break; default: writeln("Type is unknown"); break; } } While static if would be more practical for templates, my idea could be extended to dynamic upcasting of classes as well, which could be applied to exception handling: try{ ... } catch(Throwable err) switch(err){ case IOError a: break; case OutOfMemoryError b: break; default: throw err; }Yea, pattern matching, basically. Great as D is, pattern matching is one thing where Nemerle blows D out of the water: http://nemerle.org/Grok_Variants_and_matching With exceptions in particular, I've often felt that we need some sort of templated catch: try {...} catch(TypeTuple!(ExceptionA, ExceptionB) e) { // Common implementation, but NO need // for that re-throwing abomination you'd // inevitably need if you just caught // a common base type. }
Feb 18 2012
Am 19.02.2012 02:47, schrieb Nick Sabalausky:With exceptions in particular, I've often felt that we need some sort of templated catch: try {...} catch(TypeTuple!(ExceptionA, ExceptionB) e) { // Common implementation, but NO need // for that re-throwing abomination you'd // inevitably need if you just caught // a common base type. }+1 best would be with built-in Tuples, but I guess built-in tuples are just a dream …
Feb 19 2012