request switch statement with common block
Andre Artus
andre.artus at gmail.com
Sun Aug 4 21:14:07 PDT 2013
On Monday, 5 August 2013 at 04:07:55 UTC, Andre Artus wrote:
>
>>> Andre Artus:
>>> int number;
>>> string message;
>>> switch (number)
>>> {
>>> default: // valid: ends with 'throw'
>>> throw new Exception("unknown number");
>>> case 3:
>>> message ~= "three "; break;
>>> case 4:
>>> message ~= "four "; continue;
>>> case 5:
>>> message ~= "five "; goto case;
>>> case 6:
>>> message ~= "six "; break;
>>> case 1:
>>> case 2:
>>> message = "one or two";
>>> }
>>>
>>> With the inclusion of 'default' the condition covers the
>>> whole range of 'int'. The programmer may only want the pre
>>> and post code to be executed for every other case (1..6).
>
>> MattCoder:
>> Like I said, it would be nice if we could extend some D
>> features without change the compiler source, maybe like macros
>> in LISP.
>
> It may not always be the case, but in my experience this often
> leads to write-only code.
> I'm pretty new to D, so I'm not quite up to speed with the
> metaprogramming abilities, but I'm under the impression that
> this is what mixin's are for.
>
>> MattCoder:
>> The switch statement should have an event handler like:
>> onBeforeMatch or onAfterMatch to handle this.
>>
>> But for what I saw on this thread, this is only possible
>> changing the compiler source. :/
>>
>> Matheus.
>
> In order to produce the most sane (in my opinion) construct the
> code cannot be rewritten as JS suggested:
>
>> JS:
>>
>> if (cond) { <common_body1> }
>> switch (cond)
>> {
>> case <symbol> : <case body> [break or return or fallthrough]
>> ...
>> <default> : <default_body> [break or return or fallthrough]
>> }
>> if (cond) { <common_body2> }
>> if (!cond) { <else_body> }
>
> As I mentioned before `switch` takes an expression that
> evaluates to integral or char[], the condition is completed in
> the `case`. The condition leading to the 'common' entry and
> exit code must replicate that of the complete switch statement.
> This begs the question about how to handle `default`. It would
> be difficult to correctly reason about the code without
> additional information.
>
> The only suggestion that leads to sane results in all (maybe?)
> cases is that made by Ary Borenszweig.
>
>> Ary Borenszweig:
>>
>> switch(cond) {
>> case A:
>> common_code();
>> // something
>> case B:
>> common_code();
>> // something else
>> }
>
> I would think that the common code could be factored into a
> function taking a void delegate (analogous to C# Action<T>
> delegate) then passing the case specific code as a lambda. This
> is something I have done in C#, but not yet in D.
>
> In C# you would something like this:
>
> private void UseAGoodNameDescribingCommonCode(Action action)
> {
> // Entry code
> action();
> // Exit code
> }
>
> switch(expression) {
> case A:
> UseAGoodNameDescribingCommonCode(() => {
> // something
> });
> break;
> case B:
> UseAGoodNameDescribingCommonCode(() => {
> // something
> });
> break;
> default:
> // Something else
> }
>
> It's very clear where it's being applied, and where it is not.
>
> If the compiler was rewriting the following:
>
> switch(expression) {
> common_entry: // should not be order specific i.e. overloading
> 'common'
> // entry code
> break;
> common_exit:
> // exit code
> break;
> case A:
> // something
> break;
> case B:
> // something else
> break;
> default:
> // default something
> }
>
> It could produce something like this:
>
>
> switch(expression) {
> common_entry: // should not be order specific i.e. overloading
> 'common'
> // entry code
> goto pop_label();
> common_exit:
> // exit code
> break;
> case A:
> // could set var or register used push/pop for clarity of
> intent
> push_label(A_prime);
> goto case common_entry;
> label A_prime:
> // something
> goto case common_exit;
> // break not needed here;
> case B:
> // rinse & repeat
> label B_prime:
> // rinse & repeat
> default:
> // default something
> }
> What to do with default needs to be disambiguated.
I should point out that 'common_entry' and 'common_exit' are not
really cases, but labels as they are not explicitly tied to the
input expression.
More information about the Digitalmars-d
mailing list