www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Another switch suggestion.

reply Fredrik Olsson <peylow gmail.com> writes:
As the switch syntax already allows for more funky stuff than C does, 
that requires some kind of code to be inserted why not extend on it a 
bit and allow for say:

switch (foo) {
   case ($ >= 'a' && $ <= 'z') || ($ >= 'A' && $ <= 'Z'):
     doStuff();
     break;
   default:
     doOtherStuff();
     break;
}


Just as $ means "length of array" for slicing an array and such, why not 
let $ mean "the value the current switch is testing for"? And if the 
case have a boolean expression instead of a constant than the first case 
that evaluates to true should be run.

One of the few features I miss from Visual Basic :).

And an even better syntax for the above example would naturally be:
switch (foo) {
   case $ in <'a'..'z', 'A'..'Z'>:
     doStuff();
     break;
   default:
     doOtherStuff();
     break;
}


// Fredrik Olsson
Aug 31 2006
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Fredrik Olsson wrote:
 As the switch syntax already allows for more funky stuff than C does, 
 that requires some kind of code to be inserted why not extend on it a 
 bit and allow for say:
 
 switch (foo) {
   case ($ >= 'a' && $ <= 'z') || ($ >= 'A' && $ <= 'Z'):
     doStuff();
     break;
   default:
     doOtherStuff();
     break;
 }
 
 Just as $ means "length of array" for slicing an array and such, why not 
 let $ mean "the value the current switch is testing for"?

What if you want to include the value being tested as an array index?
 And if the 
 case have a boolean expression instead of a constant than the first case 
 that evaluates to true should be run.

Why restrict switch to boolean expressions and constants? Moreover, what about boolean constants - constants are still expressions, aren't they? Before I got this far, I'd figured that if a '$' is present then it would compare it with true, otherwise it would compare the input value with the value of the case expression. I'm not sure I like your idea really. Moreover, suppose you have this: switch (qwert) { case $ > 42: doStuff(); break; case yuiop[69..$] > 105; doOtherStuff(); } then what would make sense? (a) to treat $ in the second case as being the value of qwert, and to pass if the expression evaluates to true? (b) to treat $ in the second case as the length of yuiop, and because the whole thing is still a boolean expression, see if it's true (thereby not using qwert at all)? (c) to treat $ in the second case as the length of yuiop, and notice that the expression doesn't depend on $ in its meaning of the switched value and therefore compare qwert with the boolean value of the expression? Moreover, your code could just as easily be written if ((foo >= 'a' && foo <= 'z') || (foo >= 'A' && foo <= 'Z')) { doStuff(); } else { doOtherStuff(); } OK, so foo might be a whole expression, which might have a side effect or be cumbersome to write out each time. But it's probably just as efficient to assign the result to a variable first and use if statements as it would be to do what you're proposing.
 One of the few features I miss from Visual Basic :).
 
 And an even better syntax for the above example would naturally be:
 switch (foo) {
   case $ in <'a'..'z', 'A'..'Z'>:

Why have the '$' at all for this syntax? Or are you trying to propose a whole new expression syntax to be used in more than just cases? Using '<' and '>' for anything but comparison operators is bound to lead to parsing complications. That's why templates don't use this notation. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 01 2006
parent reply Fredrik Olsson <peylow gmail.com> writes:
Stewart Gordon skrev:
 Fredrik Olsson wrote:

 I'm not sure I like your idea really.  Moreover, suppose you have this:

 Moreover, your code could just as easily be written
 
     if ((foo >= 'a' && foo <= 'z') || (foo >= 'A' && foo <= 'Z')) {

an example of how the existing switch statement could be extended to solve, among some things, the tedious typing of the example you also wrote down. Visual Basic uses the keyword Is for this, C# reserver value in property setters, lisp uses ** for previous results, etc. I do not much care what D would use, only if it solves the problem. I picked $ for the example as it is already used as a "special placeholder". If it is not practical, then fine use something else. I still think the idea behind is good as it will reduce code size and make source more readable. Less code == less bugs, more readable == more maintainable.
 One of the few features I miss from Visual Basic :).

 And an even better syntax for the above example would naturally be:
 switch (foo) {
   case $ in <'a'..'z', 'A'..'Z'>:

Why have the '$' at all for this syntax? Or are you trying to propose a whole new expression syntax to be used in more than just cases? Using '<' and '>' for anything but comparison operators is bound to lead to parsing complications. That's why templates don't use this notation.

D. It should not just work for cases. A language construct that only works in one construct is pretty useless. A great language have many small constructs solving specific problems, that can be combined to infinity to solve any problem. Naturally sets, if included, should be usable in any context. So <1, 42> was only my small example of how a set literal could be constructed. But if we are top use Chris Miller's suggestions for array and struct literals, then the set literal would probably be int<>!<1, 42> instead ( using {} for struct content, [] for arrays, and <> for sets, seems plausible too me). // Fredrik Olsson
Sep 03 2006
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Fredrik Olsson wrote:
<snip>
 Yes, this is yet again a proposal to add sets and ranges from pascal to 
 D. It should not just work for cases. A language construct that only 
 works in one construct is pretty useless. A great language have many 
 small constructs solving specific problems, that can be combined to 
 infinity to solve any problem. Naturally sets, if included, should be 
 usable in any context.
 
 So <1, 42> was only my small example of how a set literal could be 
 constructed. But if we are top use Chris Miller's suggestions for array 
 and struct literals, then the set literal would probably be int<>!<1, 
 42> instead ( using {} for struct content, [] for arrays, and <> for 
 sets, seems plausible too me).

I'm still not sure if I like this notation. Maybe that would be parseable, under the provision that the by the time it spots a '<' immediately following '!' it would know that it isn't parsing a RelExpression containing a negation. And making use of the same undocumented disambiguation rule that distinguishes a pointer declaration from a MulExpression. Would it be possible to do intervals of non-builtin types? Open or semi-open intervals of floating points? Regions of the complex plane? Generally, infinite sets that aren't just intervals or unions thereof? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 03 2006