digitalmars.D - switch case for constants-only?
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Don <nospam nospam.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- "Steven Schveighoffer" <schveiguy yahoo.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Ellery Newcomer <ellery-newcomer utulsa.edu> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Ellery Newcomer <ellery-newcomer utulsa.edu> Dec 05 2009
- BCS <none anon.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- grauzone <none example.net> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- BCS <none anon.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Ellery Newcomer <ellery-newcomer utulsa.edu> Dec 05 2009
- div0 <div0 users.sourceforge.net> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- "Steven E. Harris" <seh panix.com> Dec 05 2009
- Sean Kelly <sean invisibleduck.org> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Rainer Deyke <rainerd eldwood.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Rainer Deyke <rainerd eldwood.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- Rainer Deyke <rainerd eldwood.com> Dec 05 2009
- Sean Kelly <sean invisibleduck.org> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- div0 <div0 users.sourceforge.net> Dec 05 2009
- BCS <none anon.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- BCS <none anon.com> Dec 05 2009
- "Nick Sabalausky" <a a.a> Dec 05 2009
- BCS <none anon.com> Dec 05 2009
- Don <nospam nospam.com> Dec 05 2009
- Ellery Newcomer <ellery-newcomer utulsa.edu> Dec 05 2009
- Don <nospam nospam.com> Dec 05 2009
- Ellery Newcomer <ellery-newcomer utulsa.edu> Dec 06 2009
- Don <nospam nospam.com> Dec 06 2009
- Don <nospam nospam.com> Dec 05 2009
- downs <default_357-line yahoo.de> Dec 07 2009
- retard <re tard.com.invalid> Dec 07 2009
- "Nick Sabalausky" <a a.a> Dec 07 2009
- "Simen kjaeraas" <simen.kjaras gmail.com> Dec 08 2009
- BCS <none anon.com> Dec 08 2009
- retard <re tard.com.invalid> Dec 08 2009
I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
Dec 05 2009
Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
Switch with constant values is completely different to a switch statement with variables -- it's reasonable to expect O(1) case comparisons if all the values are known at compile time, but I think that's impossible with variable cases. Allowing switch with variable cases at the expense of constant cases would be a real PITA for non-dynamic code. You'd need some way of handling both.
Dec 05 2009
"Don" <nospam nospam.com> wrote in message news:hfeilp$m1b$1 digitalmars.com...Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
Switch with constant values is completely different to a switch statement with variables -- it's reasonable to expect O(1) case comparisons if all the values are known at compile time, but I think that's impossible with variable cases.
So who's expecting switch with variable cases to be O(1)?Allowing switch with variable cases at the expense of constant cases would be a real PITA for non-dynamic code. You'd need some way of handling both.
Well, yea, that's what I'm saying: it should handle both.
Dec 05 2009
On Sat, 05 Dec 2009 16:08:00 -0500, Nick Sabalausky <a a.a> wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
you mean a real PITA to use if instead of switch? AFAIK, switch is the way it is to foster different optimizations by the compiler. I don't know if optimizations can be performed if the cases are dynamic. Also, what happens if two of the cases are dynamically the same? I think one of the optimizations is that the compiler can reorder the cases to make the testing more streamlined. -Steve
Dec 05 2009
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.u4hhjisgeav7ka localhost.localdomain...On Sat, 05 Dec 2009 16:08:00 -0500, Nick Sabalausky <a a.a> wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
you mean a real PITA to use if instead of switch?
For long "if else(x == y)" chains where the x is always the same? Yes, absolutely.AFAIK, switch is the way it is to foster different optimizations by the compiler.
If the only reason for switch were optimization, then switch would be useless because it would be easy for the compiler to detect: if(x == constVal1) {} else if(x == constVal2) {} // Etc And do the exact same optimizations.I don't know if optimizations can be performed if the cases are dynamic.
Compared to the if-else chains? Probably not. But so what?Also, what happens if two of the cases are dynamically the same?
Switch is a shorthand for a certain pattern of if-else chains, as such, it should behave the same by choosing the first and skipping the rest.I think one of the optimizations is that the compiler can reorder the cases to make the testing more streamlined.
Ok, so it just won't do that with non-constant cases.
Dec 05 2009
On 12/05/2009 03:39 PM, Nick Sabalausky wrote:"Steven Schveighoffer"<schveiguy yahoo.com> wrote in message news:op.u4hhjisgeav7ka localhost.localdomain...On Sat, 05 Dec 2009 16:08:00 -0500, Nick Sabalausky<a a.a> wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
you mean a real PITA to use if instead of switch?
For long "if else(x == y)" chains where the x is always the same? Yes, absolutely.
More so than remembering to type break after each case block?
Dec 05 2009
"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in message news:hfekll$pbl$1 digitalmars.com...On 12/05/2009 03:39 PM, Nick Sabalausky wrote:"Steven Schveighoffer"<schveiguy yahoo.com> wrote in message news:op.u4hhjisgeav7ka localhost.localdomain...On Sat, 05 Dec 2009 16:08:00 -0500, Nick Sabalausky<a a.a> wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
you mean a real PITA to use if instead of switch?
For long "if else(x == y)" chains where the x is always the same? Yes, absolutely.
More so than remembering to type break after each case block?
Good point, but that's really a separate issue.
Dec 05 2009
On 12/05/2009 04:19 PM, Nick Sabalausky wrote:"Ellery Newcomer"<ellery-newcomer utulsa.edu> wrote in messageMore so than remembering to type break after each case block?
Good point, but that's really a separate issue.
I don't know about that. The issue seems to be you want switch to behave in a manner unlike that of any other language that I know of. It's different. It breaks convention. It's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
Dec 05 2009
Hello Ellery,On 12/05/2009 04:19 PM, Nick Sabalausky wrote:"Ellery Newcomer"<ellery-newcomer utulsa.edu> wrote in messageMore so than remembering to type break after each case block?
behave in a manner unlike that of any other language that I know of.
Lisp has something that workd like this. (Not that I think D should change.)It's different. It breaks convention. It's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
vote += 0.1;
Dec 05 2009
"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in message news:hfer6b$15d1$1 digitalmars.com...On 12/05/2009 04:19 PM, Nick Sabalausky wrote:"Ellery Newcomer"<ellery-newcomer utulsa.edu> wrote in messageMore so than remembering to type break after each case block?
Good point, but that's really a separate issue.
I don't know about that. The issue seems to be you want switch to behave in a manner unlike that of any other language that I know of. It's different. It breaks convention. It's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
I definitely agree we need a new switch that isn't so stuck in C-land. And if we got it, I'd be perfectly happy to restrict all the new stuff to the newer switch and just let C-style switch atrophy into oblivion. But a new switch just doesn't seem to be happening :(. Also, I still don't see how there's any semantic difference between the current switch and the switch-like if-else chain other than just the fact that switch currently carries the restriction that the values being checked against must be unique and known at compile time.
Dec 05 2009
Nick Sabalausky wrote:"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in messageIt's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
I definitely agree we need a new switch that isn't so stuck in C-land. And if we got it, I'd be perfectly happy to restrict all the new stuff to the newer switch and just let C-style switch atrophy into oblivion. But a new switch just doesn't seem to be happening :(.
You'd still need to keep around the old switch for stuff like Duff's Device. But I agree that it'd be nice to have a new switch for the following reasons: could use pattern matching instead of just a list of values, no redundant "case", no fallthrough by default, allow a more functional programming style.
Dec 05 2009
"grauzone" <none example.net> wrote in message news:hfeu6p$1apu$1 digitalmars.com...Nick Sabalausky wrote:"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in messageIt's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
I definitely agree we need a new switch that isn't so stuck in C-land. And if we got it, I'd be perfectly happy to restrict all the new stuff to the newer switch and just let C-style switch atrophy into oblivion. But a new switch just doesn't seem to be happening :(.
You'd still need to keep around the old switch for stuff like Duff's Device. But I agree that it'd be nice to have a new switch for the following reasons: could use pattern matching instead of just a list of values, no redundant "case", no fallthrough by default, allow a more functional programming style.
I have to admit, I'm so jealous of what I've seen of Nemerle's pattern matching (and it's metaprogramming), that I've been tempted to to give a shot at switching to it for things that don't strickly need system-level capabilities.
Dec 05 2009
Hello Nick,Also, I still don't see how there's any semantic difference between the current switch and the switch-like if-else chain other than just the fact that switch currently carries the restriction that the values being checked against must be unique and known at compile time.
For one; fall thought (but that can be done with gotos or some really ugly nested if's: The other thing is that a compiler is free to be implemented a switch statement any way it wants including things like perfect hashes or (for strings) a RegEx style DFA. This does have semantic effects in the O() of the construct. I'll grant that what you are asking for is useful. But I will not go so far as to say that the current switch construct or even it's name (it has about as much to do with switch as for has to do with while) should be co opted for it. I'll even go so far as to say that I really doubt that the current switch will atrophy even if another construct is added with these features.
Dec 05 2009
"BCS" <none anon.com> wrote in message news:a6268ffdcba8cc43e0db895786 news.digitalmars.com...Hello Nick,Also, I still don't see how there's any semantic difference between the current switch and the switch-like if-else chain other than just the fact that switch currently carries the restriction that the values being checked against must be unique and known at compile time.
For one; fall thought (but that can be done with gotos or some really ugly nested if's:
Right, it all maps out.The other thing is that a compiler is free to be implemented a switch statement any way it wants including things like perfect hashes or (for strings) a RegEx style DFA. This does have semantic effects in the O() of the construct.
I'd consider that more a matter of optimization. I know there's a lot of people here that disagree with me on this, but I don't consider time complexity a semantics issue, except for very, very explicit cases or possibly for (true) real-time.I'll grant that what you are asking for is useful. But I will not go so far as to say that the current switch construct or even it's name (it has about as much to do with switch as for has to do with while)
*shrug* I've alwayd thought of while as nothing more than (a very welcome) syntactic sugar for 'for'.should be co opted for it. I'll even go so far as to say that I really doubt that the current switch will atrophy even if another construct is added with these features.
Dec 05 2009
On 12/05/2009 06:25 PM, Nick Sabalausky wrote:Also, I still don't see how there's any semantic difference between the current switch and the switch-like if-else chain other than just the fact that switch currently carries the restriction that the values being checked against must be unique and known at compile time.
If I understand switch correctly, it is analogous to this: a = x; if( a == exp1) goto Case1; if( a == exp2) goto Case2; ... if( a == expN) goto CaseN; assert(0); Case1: ... Case2: ... ... CaseN: ... except that the case expressions aren't required to be in any order and the compiler has a fair amount of freedom in implementing those conditional jumps. Conceivably, you could even forgo the if statements and have computed goto statements if your cases are nice enough. Also note the value being compared doesn't change while it is being compared. If statements are a bit less disciplined in that regard.
Dec 05 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ellery Newcomer wrote:On 12/05/2009 04:19 PM, Nick Sabalausky wrote:"Ellery Newcomer"<ellery-newcomer utulsa.edu> wrote in messageMore so than remembering to type break after each case block?
Good point, but that's really a separate issue.
I don't know about that. The issue seems to be you want switch to behave in a manner unlike that of any other language that I know of. It's different. It breaks convention.
PHP allows runtime vars as cases in switch. Though whether anybody round here considers PHP a real language is another matter. I'm in favour; requiring the case statements to be constants seem to be an optimisation requirement, rather than there being some actual reason for it. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFLGwYmT9LetA9XoXwRAkd8AJ9m0MapxiSSpWnQ19Xcsh26LO/qgQCgm9+t QocozVfJymylNHD76L4Pbq0= =qE1v -----END PGP SIGNATURE-----
Dec 05 2009
"div0" <div0 users.sourceforge.net> wrote in message news:hff0n1$1f6t$1 digitalmars.com...-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ellery Newcomer wrote:On 12/05/2009 04:19 PM, Nick Sabalausky wrote:"Ellery Newcomer"<ellery-newcomer utulsa.edu> wrote in messageMore so than remembering to type break after each case block?
Good point, but that's really a separate issue.
I don't know about that. The issue seems to be you want switch to behave in a manner unlike that of any other language that I know of. It's different. It breaks convention.
PHP allows runtime vars as cases in switch. Though whether anybody round here considers PHP a real language is another matter.
PHP is very real. Just like Cancer and AIDS. ;)
Dec 05 2009
BCS <none anon.com> writes:Lisp has something that workd like this.
Did you mean the "case" family=B9 of forms? ,---- | CL-USER> (case 3 | (1 "foo") | (2 "bar") | (otherwise "baz")) | "baz" | CL-USER> (case 4 | (1 "foo") | ((2 4) "bar") | (otherwise "baz")) | "bar" `---- There's also the similar "typecase" family=B2. Footnotes:=20 =B9 http://www.lispworks.com/documentation/HyperSpec/Body/m_case_.htm =B2 http://www.lispworks.com/documentation/HyperSpec/Body/m_tpcase.htm --=20 Steven E. Harris
Dec 05 2009
Nick Sabalausky Wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
int x = 1, y = 1; switch( z ) { case x: ... case y: ... } What should this do? Throw an exception perhaps?
Dec 05 2009
"Sean Kelly" <sean invisibleduck.org> wrote in message news:hfelka$rhf$1 digitalmars.com...Nick Sabalausky Wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
int x = 1, y = 1; switch( z ) { case x: ... case y: ... } What should this do? Throw an exception perhaps?
As I mentioned earlier, that should be semantically equivilent to: int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
Dec 05 2009
Nick Sabalausky wrote:As I mentioned earlier, that should be semantically equivilent to: int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
I assume the same rule applies to 'goto case'? int i = 0, j = 0; switch (0) { case i: goto case j; // Oops, infinite loop. case j: // Never reached. } I'm basically in favor of this change - it increases the expressive power and uniformity of the language at little cost - but corner cases like this bother me. -- Rainer Deyke - rainerd eldwood.com
Dec 05 2009
"Rainer Deyke" <rainerd eldwood.com> wrote in message news:hfenkl$veq$1 digitalmars.com...Nick Sabalausky wrote:As I mentioned earlier, that should be semantically equivilent to: int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
I assume the same rule applies to 'goto case'? int i = 0, j = 0; switch (0) { case i: goto case j; // Oops, infinite loop. case j: // Never reached. } I'm basically in favor of this change - it increases the expressive power and uniformity of the language at little cost - but corner cases like this bother me.
I think that amounts to a computed goto, which I don't think D currently has, so that probably just wouldn't compile. But with or without computerd goto, this sounds like a reason to use an actual fallthrough command instead of "goto case".
Dec 05 2009
Nick Sabalausky wrote:"Rainer Deyke" <rainerd eldwood.com> wrote in message news:hfenkl$veq$1 digitalmars.com...I assume the same rule applies to 'goto case'?
I think that amounts to a computed goto, which I don't think D currently has, so that probably just wouldn't compile.
So case labels could be variables but labels for 'goto case' would be constant? That seems backwards and inconsistent. It also fails to address this: int i = 0, j = 0; switch (j) { case i: break; case j: // Never reached. }But with or without computerd goto, this sounds like a reason to use an actual fallthrough command instead of "goto case".
Not really. If you want fallthrough, use 'goto case' without a label, like this: goto case; -- Rainer Deyke - rainerd eldwood.com
Dec 05 2009
"Rainer Deyke" <rainerd eldwood.com> wrote in message news:hfeu0m$1af9$1 digitalmars.com...Nick Sabalausky wrote:"Rainer Deyke" <rainerd eldwood.com> wrote in message news:hfenkl$veq$1 digitalmars.com...I assume the same rule applies to 'goto case'?
I think that amounts to a computed goto, which I don't think D currently has, so that probably just wouldn't compile.
So case labels could be variables but labels for 'goto case' would be constant? That seems backwards and inconsistent.
I guess I don't see it as inconsistent because I don't see case labels quite so much as goto labels but moreso as just an (awkward) syntax for pattern matching.It also fails to address this: int i = 0, j = 0; switch (j) { case i: break; case j: // Never reached. }
I don't see why it would need to. Switch compares values, not identifiers. If that needed to be addressed, then this would also need to be addressed: int i = 0, j = 0; if(j == i) {} else if(j == j) { /+ never reached +/ } And maybe you could argue that does need to be addressed too, but at that point it's no longer an issue of switch accepting or rejecting run-time values.But with or without computerd goto, this sounds like a reason to use an actual fallthrough command instead of "goto case".
Not really. If you want fallthrough, use 'goto case' without a label, like this: goto case;
Ahh, yea, good point. Does that currently work?
Dec 05 2009
Nick Sabalausky wrote:"Rainer Deyke" <rainerd eldwood.com> wrote in message news:hfeu0m$1af9$1 digitalmars.com...So case labels could be variables but labels for 'goto case' would be constant? That seems backwards and inconsistent.
I guess I don't see it as inconsistent because I don't see case labels quite so much as goto labels but moreso as just an (awkward) syntax for pattern matching.
The question is how to make 'goto case' work with the improved switch statements without breaking compatibility or creating an artificial distinction between static and dynamic switch statements. The obvious solution is to rewrite this: switch (n) { case a: goto case b; ... } ...as this: __switch_value = n; __switch_start: switch (__switch_value) { case a: __switch_value = b; goto __switch_start; ... } This rewrite preserves the current semantics of 'goto case' while allowing the case label to be an arbitrary expression, both in the actual label and in the 'goto case' statement. The "computed goto" effect is a natural consequence of the rewrite.It also fails to address this:
I don't see why it would need to.
It doesn't need to, but it makes 'switch' statements slightly more error-prone. That's a small but real and measurable loss.goto case;
Ahh, yea, good point. Does that currently work?
It should. I don't have a D compiler around to test it. -- Rainer Deyke - rainerd eldwood.com
Dec 05 2009
Nick Sabalausky Wrote:"Sean Kelly" <sean invisibleduck.org> wrote in message news:hfelka$rhf$1 digitalmars.com...Nick Sabalausky Wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
int x = 1, y = 1; switch( z ) { case x: ... case y: ... } What should this do? Throw an exception perhaps?
As I mentioned earlier, that should be semantically equivilent to: int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
D allows duplicate case values? I thought this was a compile error.
Dec 05 2009
"Sean Kelly" <sean invisibleduck.org> wrote in message news:hfeqbg$143u$1 digitalmars.com...Nick Sabalausky Wrote:"Sean Kelly" <sean invisibleduck.org> wrote in message news:hfelka$rhf$1 digitalmars.com...Nick Sabalausky Wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
int x = 1, y = 1; switch( z ) { case x: ... case y: ... } What should this do? Throw an exception perhaps?
As I mentioned earlier, that should be semantically equivilent to: int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
D allows duplicate case values? I thought this was a compile error.
I slightly mis-spoke. I meant if you take a current valid switch statement, then that switch statement is semantically equivilent to the above pattern, and if you take something in the patten above that fits switch's current "unique and known at compile-time" restrictions, then that's equivilant to a certain switch statement. I guess what I was really saying is that the "unique" requirement makes sense when the values are all known at compile-time, because it's amounts to this... if(z == 1) { ... } else if(z == 1) { /+ dead code +/ } ...but when they're not known at compile-time, that reasoning (along with the resulting restriction) is no longer applicable. Note though, that I'm not necissarily advocating the removal of that restriction from known-at-compile-time values, just for values known only at runtime.
Dec 05 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Sean Kelly wrote:In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
D allows duplicate case values? I thought this was a compile error.
It does; from the switch spec: ==== Case expressions must all evaluate to distinct values. Const or immutable variables must all have different names. If they share a value, the first case statement with that value gets control. There may not be two or more default statements. ==== Which seems sensible and should apply to the runtime evaluated case statements as well if that gets added. Haven't tested that though to see if that is actually what happens. - -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iD8DBQFLGwKaT9LetA9XoXwRAoAJAKDF2NucN7mcZOgPuleV+Q4HosyTkQCgh2GB EL4RJGfZBK/2nC3iM0ySjWw= =L2pb -----END PGP SIGNATURE-----
Dec 05 2009
Hello Nick,"Sean Kelly" <sean invisibleduck.org> wrote in message news:hfelka$rhf$1 digitalmars.com...Nick Sabalausky Wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
switch( z ) { case x: ... case y: ... } What should this do? Throw an exception perhaps?
int x = 1, y = 1; if(z == x) { ... } else if(z == y) { ... } In fact, it's already semantically equivilent to that, except that x and y are currently required to be known at compile-time.
Just jumping a ways down this rabbit hole... struct S { int i; int opCmp(S s) { return i-- == s.i++; } { S a,b,c,d,e; ... switch(a) { case b: break; case c: break; case d: break; case e: break; } } Oh, boy. What the hack does the above do?
Dec 05 2009
"BCS" <none anon.com> wrote in message news:a6268ffdcb78cc43db75126b3c news.digitalmars.com...Just jumping a ways down this rabbit hole... struct S { int i; int opCmp(S s) { return i-- == s.i++; } { S a,b,c,d,e; ... switch(a) { case b: break; case c: break; case d: break; case e: break; } } Oh, boy. What the hack does the above do?
It blatantly abuses operator overloading ;) Start doing stuff like that, and you'll wind up in wonderland even without changing switch.
Dec 05 2009
Hello Nick,"BCS" <none anon.com> wrote in message news:a6268ffdcb78cc43db75126b3c news.digitalmars.com...Just jumping a ways down this rabbit hole... struct S { int i; int opCmp(S s) { return i-- == s.i++; } { S a,b,c,d,e; ... switch(a) { case b: break; case c: break; case d: break; case e: break; } } Oh, boy. What the hack does the above do?
that, and you'll wind up in wonderland even without changing switch.
Ok then how about: switch(c) { case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; } Are you only going to allow pure functions and expressions with no side effects? I'd guess you could try and set down the list of rules that makes this sane but it's not something I'd like to try any time soon.
Dec 05 2009
"BCS" <none anon.com> wrote in message news:a6268ffdcc98cc43ebb9955246 news.digitalmars.com...Hello Nick,"BCS" <none anon.com> wrote in message news:a6268ffdcb78cc43db75126b3c news.digitalmars.com...Just jumping a ways down this rabbit hole... struct S { int i; int opCmp(S s) { return i-- == s.i++; } { S a,b,c,d,e; ... switch(a) { case b: break; case c: break; case d: break; case e: break; } } Oh, boy. What the hack does the above do?
that, and you'll wind up in wonderland even without changing switch.
Ok then how about: switch(c) { case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; case getc(): ..... break; }
I think we can reasonably expect run-time-value cases to be checked in order (or at least whenever the optimizer can't guarantee that it won't matter), so that then becomes pretty simple: If the nth character the user enters (up to the number of cases) matches c, then the nth case is executed, and only the first match is used. I'm not sure it would make much sense to use every match. Switch is a selector, not a multiplexer.Are you only going to allow pure functions and expressions with no side effects?
That could be worth exploring. But for now, I'd say no.I'd guess you could try and set down the list of rules that makes this sane but it's not something I'd like to try any time soon.
The rule is simple: Just translate it to an if-else chain.
Dec 05 2009
The point I'm trying to make is that a trivial translation to an if else chain is not the only realistic choice. What you propose is non trivial and, in a few minuets of thinking I've already thought of a number of ways it breaks the expected semantics of the classic switch statement (it can end up with worse than linear cost for one) and a small slew of potential issues. Personably, I don't see the value in it. It sits on an odd kind of place where it has a statically defined number of options but they are dynamically defined as to what they are. I rather suspect that in most cases both of these will be static or dynamic. I've never had a case where I needed to use the construct you describe and I can think of ways to get the same effect without the potential for problems. As a result, I think you have set your self a really hard task of arguing that it has more advantages than problems.
Dec 05 2009
Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
Dec 05 2009
On 12/05/2009 09:20 PM, Don wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
But not dynamic ones It is a surprise though.
Dec 05 2009
Ellery Newcomer wrote:On 12/05/2009 09:20 PM, Don wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
But not dynamic ones It is a surprise though.
Eg, this works: for (int i=0; i<10; ++i) { switch(x) { case 3: break; case i: break; default: } }
Dec 05 2009
On 12/05/2009 11:17 PM, Don wrote:Ellery Newcomer wrote:On 12/05/2009 09:20 PM, Don wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
But not dynamic ones It is a surprise though.
Eg, this works: for (int i=0; i<10; ++i) { switch(x) { case 3: break; case i: break; default: } }
Oop. Never mind. I was looking at void main(string[] args){ int i = to!(int)(args[1]); switch(i){ case args.length: writeln("hey!"); } } Now I'm really surprised.
Dec 06 2009
Ellery Newcomer wrote:On 12/05/2009 11:17 PM, Don wrote:Ellery Newcomer wrote:On 12/05/2009 09:20 PM, Don wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
But not dynamic ones It is a surprise though.
Eg, this works: for (int i=0; i<10; ++i) { switch(x) { case 3: break; case i: break; default: } }
Oop. Never mind. I was looking at void main(string[] args){ int i = to!(int)(args[1]); switch(i){ case args.length: writeln("hey!"); } } Now I'm really surprised.
The spec says: "The case expressions must all evaluate to a constant value or array, or a runtime initialized const or immutable variable of integral type. " But in reality, it seems that the cases can either be int or string symbols or expressions. If they are expressions, they are evaluated at compile time. That's quite nice, as it avoids the downsides which BCS and I had mentioned. Maybe it's too much of a special case though? Seems like yet another Easter egg. Or else it's a bug.
Dec 06 2009
Ellery Newcomer wrote:On 12/05/2009 09:20 PM, Don wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I actually tested this. I was surprised. In D2, variables are allowed...
But not dynamic ones It is a surprise though.
It might just be bug 2414.
Dec 05 2009
Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I wish they'd get over it. import tools.base; ... mixin( ReplaceConcat!(2, "if (x == #) { ! } else", "#", "!", "A", "handleTheACase; ", "B", "handleTheBCase; ", "C", "handleTheCCase; " ) ~ " assert(false); " );
Dec 07 2009
Mon, 07 Dec 2009 16:55:43 +0100, downs wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
import tools.base; ... mixin( ReplaceConcat!(2, "if (x == #) { ! } else", "#", "!", "A", "handleTheACase; ", "B", "handleTheBCase; ", "C", "handleTheCCase; " ) ~ " assert(false); " );
That reminded me.. I should write a case-of mixin some day: auto result = mixin case_of(foo, ` Tree(l,r) => "We have children "~l.toString()~" and "~r.toString() Nil => "It's a leaf" `);
Dec 07 2009
"downs" <default_357-line yahoo.de> wrote in message news:hfj8qb$ps2$1 digitalmars.com...Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I wish they'd get over it. import tools.base; ... mixin( ReplaceConcat!(2, "if (x == #) { ! } else", "#", "!", "A", "handleTheACase; ", "B", "handleTheBCase; ", "C", "handleTheCCase; " ) ~ " assert(false); " );
That's just ugly.
Dec 07 2009
On Mon, 07 Dec 2009 16:55:43 +0100, downs <default_357-line yahoo.de> wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
I wish they'd get over it. import tools.base; ... mixin( ReplaceConcat!(2, "if (x == #) { ! } else", "#", "!", "A", "handleTheACase; ", "B", "handleTheBCase; ", "C", "handleTheCCase; " ) ~ " assert(false); " );
Now if only D templates handled variadic alias parameters, and my idea of mixin templates, we could instead have this syntax: int n; SwitchCase!( n, A, handleA(), B, handleB(), C, handleC(), assert( false ) ); -- Simen
Dec 08 2009
Hello Simen,On Mon, 07 Dec 2009 16:55:43 +0100, downs <default_357-line yahoo.de> wrote:Nick Sabalausky wrote:I just noticed in D1 that the values for the cases in a switch must be known at compile-time (btw, the docs don't seem somewhat vague on that). Is this also true in D2? If so, I don't suppose we could get that changed before the book? It's a real PITA for dynamic code.
import tools.base; ... mixin( ReplaceConcat!(2, "if (x == #) { ! } else", "#", "!", "A", "handleTheACase; ", "B", "handleTheBCase; ", "C", "handleTheCCase; " ) ~ " assert(false); " );
I want this (for other reasons).and my idea of mixin templates, we could instead have this syntax: int n; SwitchCase!( n, A, handleA(), B, handleB(), C, handleC(), assert( false ) );
I think you ca get this to work right now: SwitchCase!(n). Case!(A, handleA). Case!(B, handleB). Case!(C, handleC). DefaultFail!();
Dec 08 2009
Sat, 05 Dec 2009 20:03:28 -0500, Nick Sabalausky wrote:"grauzone" <none example.net> wrote in message news:hfeu6p$1apu$1 digitalmars.com...Nick Sabalausky wrote:"Ellery Newcomer" <ellery-newcomer utulsa.edu> wrote in messageIt's a useful divergence. It's a feature that should exist. But I contend it makes more sense to make a new construct which *is* equivalent to a certain pattern of nested ifs (switch isn't) and incorporate your feature into that than to shoehorn it into switch.
I definitely agree we need a new switch that isn't so stuck in C-land. And if we got it, I'd be perfectly happy to restrict all the new stuff to the newer switch and just let C-style switch atrophy into oblivion. But a new switch just doesn't seem to be happening :(.
You'd still need to keep around the old switch for stuff like Duff's Device. But I agree that it'd be nice to have a new switch for the following reasons: could use pattern matching instead of just a list of values, no redundant "case", no fallthrough by default, allow a more functional programming style.
I have to admit, I'm so jealous of what I've seen of Nemerle's pattern matching (and it's metaprogramming), that I've been tempted to to give a shot at switching to it for things that don't strickly need system-level capabilities.
I sense words of heresy! TBH pattern matching is pretty nice. But given the amount of time we have left before D2 is out, I don't really expect anything to change anymore. D3 might not be ever released if D2 fails. And I somehow can't see the D community embracing the functional programming paradigm.
Dec 08 2009









"Nick Sabalausky" <a a.a> 