Dispatching on a variant
Jeremie Pelletier
jeremiep at gmail.com
Sat Sep 26 13:50:36 PDT 2009
Jarrett Billingsley wrote:
> On Sat, Sep 26, 2009 at 4:18 PM, Jeremie Pelletier <jeremiep at gmail.com> wrote:
>
>>> type Event = Mouse | Key | Move;
>> This can be confusing, for example the first thing that comes to mind for me
>> is that Event is the bitwise OR result of 3 constants, not an enumerated
>> type.
>>
>> Besides, how is it any different than:
>>
>> enum { Mouse, Key, Move };
>
> It's not an enumerated constant. Mouse, Key, and Move are all types,
> and Event is a discriminated union of the three. See more below.
>
>> match(event) is no different than switch(event), except that pattern
>> matching often implies runtime semantics and is often slower than a straight
>> jump table generated from a switch.
>
> Not in this case. See, when you would do "type Event = Mouse | Key |
> Move", it's actually more like doing:
>
> struct Event
> {
> enum Type { Mouse, Key, Move }
> Type type;
> union
> {
> Mouse m;
> Key k;
> Move v;
> }
> }
>
> Then, when you do "match(e) { Mouse m => ... }" it's actually being turned into:
>
> switch(e.type)
> {
> case Event.Type.Mouse: alias e.m m; ...
> case Event.Type.Key: alias e.k k; ...
> }
>
> Basically discriminated unions get rid of this annoying boilerplate
> that you have to use every time you want a tagged union.
Oh, that makes sense, but I don't see why you need language support for
that, a variant type should be able to get most of it using type tuples,
maybe just add support to switch on type tuples along with an opSwitch()
method:
alias Algebraic!(Mouse, Key, Move) Event;
final switch(Event) {
case Mouse:
case Key:
case Move:
}
Jeremie
More information about the Digitalmars-d
mailing list