View mode: basic / threaded / horizontal-split · Log in · Help
October 30, 2012
Re: What is the use case for this weird switch mecanism
On Tue, Oct 30, 2012 at 04:51:33PM -0400, Nick Sabalausky wrote:
> On Tue, 30 Oct 2012 21:39:31 +0100
> deadalnix <deadalnix@gmail.com> wrote:
> 
> > Le 30/10/2012 18:57, Andrej Mitrovic a écrit :
> > > On 10/30/12, Philippe Sigaud<philippe.sigaud@gmail.com>  wrote:
> > >> I've no idea why it's authorized
> > >
> > > There could be a label for a goto there.
> > 
> > That still don't explain what the use case is.
> 
> Obfuscated coding contests?

Is this the official announcement for the inception of the IODCC? ;-) 
(cf. www.ioccc.org).


T

-- 
Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete Bleackley
October 30, 2012
Re: What is the use case for this weird switch mecanism
Era Scarecrow:

>  Maybe variable declaration (as long as they are default(s))? 
> Has a certain amount of sense, but makes more sense to do it 
> outside the switch case...

Declaring variables there is dangerous:

import std.stdio;
struct Foo {
    int x = 10;
}
void main() {
    int bar;
    switch(bar) {
        Foo f;
        case 10: break;
        default: writeln(f); // prints garbage
    }
}


Bye,
bearophile
October 30, 2012
Re: What is the use case for this weird switch mecanism
On Tuesday, 30 October 2012 at 21:40:26 UTC, bearophile wrote:
> Era Scarecrow:
>> Maybe variable declaration (as long as they are default(s))?
> Declaring variables there is dangerous:

>     switch(bar) {
>         Foo f;
>         case 10: break;
>         default: writeln(f); // prints garbage
>     }

 Then it's as though it were '= void;' by default. Most curious. 
Honestly I'd say it's illegal to have something before any 
callable case; Besides for goto's it's illegal to jump past 
declarations, yet this switch case allows it.

 I'd say one of two things must happen then.

  1) Code before the first case is disallowed
  2) Code before the first case always runs

 Option 2 seems silly and unneeded, except it allows a small 
scope during the switch call, which is it's only possible 
advantage. The only other advantage is you could have a case 
disabled and enable it during certain debugging cases, but in 
those cases why not do the whole block?

>     switch(bar) {
          static if (DEBUG) {
              case -10: /*disabled case, or something like that*/
          }
          Foo f;
>         case 10: break;
October 30, 2012
Re: What is the use case for this weird switch mecanism
"deadalnix" <deadalnix@gmail.com> wrote in message 
news:k6ouhh$116v$1@digitalmars.com...
> Today, I noticed by digging into D details the following construct :
>
> [snip switch being stupid]
>
> What the hell statement is supposed to do ? And what is the use case for 
> this ?

The structure for switch is:
switch(value) Statement(s)

There is very little structure imposed on the statements it contains.  If 
there are any case or default labels inside the switch that are not inside 
another inner switch, they are linked to the value and can be jumped to.

One (the only?) use case for the loose definition is Duff's Device.

The reason it's like this in D: that's how it is in C.
October 31, 2012
Re: What is the use case for this weird switch mecanism
Some related actual code from a while back:

##################################################
ParseTree prune ( ParseTree p ) {
    p.children = p.children.dup;
    foreach ( ref child ; p.children ) {
        child = prune( child );
    }

    switch ( p.ruleName ) {
        // strip prefix/suffix terminals, then if left with only 
one child, skip over it
        case "Args"             :
        case "List"             :
        case "Params"           :
        case "Table"            :   p.children = p.children[ 1 .. 
$ - 1 ];
                                    if ( p.children.length == 1 ) 
{

        // skip over immediate child (always a "Series")
        case "QualIdent"        :
        case "Type"             :       p.children = p.children[ 
0 ].children;
                                    }
                                    break;

        // skip self if it has exactly one child
        case "Addition"         :
        case "BoolAnd"          :
        case "BoolOr"           :
        case "Comparison"       :
        case "Conditional"      :
        case "MaybeParens"      :
        case "Multiplication"   :
        case "Postfix"          :
        case "Primary"          :
        case "Unary"            :   if ( p.children.length == 1 ) 
{

        // skip self
        case "Expression"       :
        case "Field"            :
        case "Ident"            :
        case "Literal"          :
        case "PathElem"         :
        case "Statement"        :       p = p.children[ 0 ];
                                    }
                                    break;

        default:
    }

    return p;
}
##################################################

Without the loosely defined switch() statement syntax, this would 
have been a royal pain to piece together.  Especially when each 
block of cases was evolving over time.

There is also the trick of doing 'switch(val) with(EnumType) 
{...}' to bring an enum's members into scope so that cases can be 
written as 'case Foo:' rather than 'case EnumType.Foo:'.

-- Chris Nicholson-Sauls
October 31, 2012
Re: What is the use case for this weird switch mecanism
Chris Nicholson-Sauls:

> There is also the trick of doing 'switch(val) with(EnumType) 
> {...}'

What about writing with(EnumType) switch(val) {...} ?

Bye,
bearophile
October 31, 2012
Re: What is the use case for this weird switch mecanism
On Wednesday, 31 October 2012 at 22:01:36 UTC, bearophile wrote:
> Chris Nicholson-Sauls:
>
>> There is also the trick of doing 'switch(val) with(EnumType) 
>> {...}'
>
> What about writing with(EnumType) switch(val) {...} ?

 Maybe... But a problem arises when it's function wide, and 
should be able to replace (hopefully) any block. Assuming there's 
no syntactical issues that may break other code.

int func()
with(EnumType) { //won't compile

}

int func() {
  with(EnumType) { //compiles but seems excessive when it doesn't 
need to...

  }
}

 But 'switch with' seems the proper way to put it in my mind.
October 31, 2012
Re: What is the use case for this weird switch mecanism
Era Scarecrow:

>  But 'switch with' seems the proper way to put it in my mind.

It's not worth the unsafety of the whole switch.

Bye,
bearophile
October 31, 2012
Re: What is the use case for this weird switch mecanism
On Wednesday, 31 October 2012 at 22:58:32 UTC, bearophile wrote:
> Era Scarecrow:
>> But 'switch with' seems the proper way to put it in my mind.
>
> It's not worth the unsafety of the whole switch.

 What? I'd need a little explanation what you'd mean. besides, 
'switch with' and 'with switch' are practically identical... 
aren't they?
November 05, 2012
Re: What is the use case for this weird switch mecanism
Le 31/10/2012 21:33, Chris Nicholson-Sauls a écrit :
> Some related actual code from a while back:
>
> ##################################################
> ParseTree prune ( ParseTree p ) {
> p.children = p.children.dup;
> foreach ( ref child ; p.children ) {
> child = prune( child );
> }
>
> switch ( p.ruleName ) {
> // strip prefix/suffix terminals, then if left with only one child, skip
> over it
> case "Args" :
> case "List" :
> case "Params" :
> case "Table" : p.children = p.children[ 1 .. $ - 1 ];
> if ( p.children.length == 1 ) {
>
> // skip over immediate child (always a "Series")
> case "QualIdent" :
> case "Type" : p.children = p.children[ 0 ].children;
> }
> break;
>
> // skip self if it has exactly one child
> case "Addition" :
> case "BoolAnd" :
> case "BoolOr" :
> case "Comparison" :
> case "Conditional" :
> case "MaybeParens" :
> case "Multiplication" :
> case "Postfix" :
> case "Primary" :
> case "Unary" : if ( p.children.length == 1 ) {
>
> // skip self
> case "Expression" :
> case "Field" :
> case "Ident" :
> case "Literal" :
> case "PathElem" :
> case "Statement" : p = p.children[ 0 ];
> }
> break;
>
> default:
> }
>
> return p;
> }
> ##################################################
>
> Without the loosely defined switch() statement syntax, this would have
> been a royal pain to piece together. Especially when each block of cases
> was evolving over time.
>
> There is also the trick of doing 'switch(val) with(EnumType) {...}' to
> bring an enum's members into scope so that cases can be written as 'case
> Foo:' rather than 'case EnumType.Foo:'.
>
> -- Chris Nicholson-Sauls
>

Wow this is not actually the case presented in y first post, but still 
very interesting.
1 2 3
Top | Discussion index | About this forum | D home