Dispatching on a variant

language_fan foo at bar.com.invalid
Sat Sep 26 15:05:27 PDT 2009


Sat, 26 Sep 2009 16:50:36 -0400, Jeremie Pelletier thusly wrote:

> 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:
> }

It does not need language support, but is considered fundamental in some 
languages, thus offered as built-in construct. Yep, my code was a bit 
hastily written. Of course I meant the enumerated entities also support 
subtype relation in an OOP language. For an example, see case classes in 
Scala. Even in Java enums are more powerful than in D - the only 
advantage D has is the conversion rules with primitive types.



More information about the Digitalmars-d mailing list