digitalmars.D - Type deduction using switch case
- "Xinok" <xinok live.com> Feb 18 2012
- "Robert Jacques" <sandford jhu.edu> Feb 18 2012
- "Nick Sabalausky" <a a.a> Feb 18 2012
- David <d dav1d.de> Feb 19 2012
- "Xinok" <xinok live.com> Feb 18 2012
- "Robert Jacques" <sandford jhu.edu> Feb 18 2012
- "Xinok" <xinok live.com> Feb 19 2012
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
"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
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: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.
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.
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: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.
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 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: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; } }
uses the type incorrectly, it won't compile. It also doesn't allow for dynamic upcasting of classes as in my second example.
Feb 19 2012









"Robert Jacques" <sandford jhu.edu> 