type set

spir denis.spir at gmail.com
Mon Feb 28 09:50:21 PST 2011


On 02/28/2011 03:50 PM, Steven Schveighoffer wrote:
> On Mon, 28 Feb 2011 09:27:36 -0500, spir <denis.spir at gmail.com> wrote:
>
>> By the way, the block of the function is a series of static if-s, one for
>> each allowed type. Is there any static switch? Or any other nicer way to
>> write it than:
>>
>> T check (T) () if (
>> is(T == DLogical) ||
>> is(T == DNumber) ||
>> is(T == DText) ||
>> is(T == DList) ||
>> is(T == DUnit)
>> ) {
>> TypeCode type;
>>
>> static if (is(T == DLogical))
>> if (this.code == LOGICAL)
>> return this.logical;
>> else
>> type == LOGICAL;
>> static if (is(T == DNumber))
>> if (this.code == NUMBER)
>> return this.number;
>> else
>> type == NUMBER;
>> static if (is(T == DText))
>> if (this.code == TEXT)
>> return this.text;
>> else
>> type == TEXT;
>> static if (is(T == DList))
>> if (this.code == LOGICAL)
>> return this.list;
>> else
>> type == LOGICAL;
>> static if (is(T == DUnit))
>> if (this.code == UNIT)
>> return this.unit;
>> else
>> type == UNIT;
>>
>> // type error
>> throw new TypeError(type, this);
>> }
>
> There is a final switch, but I don't know if that works on types. You may be
> stuck with static if.
>
> When doing things like this, I'd recommend using a mapping template. For example:
>
> private template typeCode(T)
> {
> static if(is(T == DLogical)) enum typeCode = LOGICAL;
> else static if(is(T == DNumber)) enum typeCode = NUMBER;
> ...
> else static assert(0);
> }
>
> then you almost can use this to generate the right code:
>
> if(this.code == typeCode!T)
> {
> static if(is(T == DUnit)) return this.unit;
> else static if(...
> }

That's it! This actually builds an the equivalent of an AA which keys are 
types. I was looking for such a functionality for a while already.
I am in fact *contantly* annoyed in D by the fact there are no types (I mean at 
runtime). On the other hand, this forces me looking for workaround, to express 
my models in "distorted" ways, which lets me discover unusual features and 
idioms in D's semantic dark corners ;-)

> You can probably replace the inner static if with a mixin, if you name your
> union members properly (i.e. if you can generate the name of the union member
> based on its type name or code, like DUnit dunit_val).

Yeah, I could, as shown by the code above: lang type Xyz <--> code XYZ <--> D 
impl type DXyz <--> union member xyz.
Could not be more regular, I guess ;-)
But as you may know, I 100% against string mixins. I prefere keeping the 
mapping explicite without string sorcery.
(Precisely, in the toy lang I'm starting to realise, one could do that 
trivially by manipulating the AST, without any dark magic. But this is another 
story...)

> But at least it gives you an idea of how this can be done efficiently.
>
> Plus avoiding large repetitive static ifs can save you from tedious
> copy-pasting bugs like the one in your DList branch ;)

Good catch, Steve! And thank you again.

PS: Is it your email client that eats whitespace (see my code above)?

Denis
-- 
_________________
vita es estrany
spir.wikidot.com



More information about the Digitalmars-d-learn mailing list