Sat, 26 Sep 2009 12:25:23 -0400, Jeremie Pelletier thusly wrote:

> Justin Johansson wrote:
>> language_fan Wrote:
>> 
>>> Sat, 26 Sep 2009 09:32:55 -0400, Justin Johansson thusly wrote:
>>>
>>>> I've had a good poke around the forums and couldn't find anything on
>>>> this so ...
>>>>
>>>> What's the recommended method for dispatching code off the runtime
>>>> type of a variant variable (Phobos D2 std.variant)?
>>>>
>>>> Does one use a bunch of
>>>>
>>>> if ( var.peek!(type1)) { ... }
>>>> else if ( var.peek!(type2)  { ... }
>>>>
>>>> for all N possible types, or is there a better & faster way with a
>>>> switch or jump table of sorts?
>>> If the type count gets large, how fast it is depends on the backend
>>> optimizations of the compiler. In the worst case it is a O(n) time
>>> linear search. A jump table or almost any other way of dispatching
>>> would be faster. If the variant had an integral tag field, it could be
>>> used in a switch; that way the compiler could easily optimize it
>>> further with the currently available constructs.
>>>
>>> This problem is solved in higher level languages by providing pattern
>>> matching constructs. The compiler is free to optimize the code the way
>>> it likes:
>>>
>>>   case var of
>>>     type1 => ...
>>>     type2 => ...
>>>     ...
>>>
>>> But since no C-like language has ever implemented pattern matching, it
>>> might be too radical to add it to D.
>> 
>> Thanks both for replies.
>> 
>> I've got about 2 dozen types in the variant so the O(n) really hurts.
>> The variant thing seemed like a really cool idea at the time but now
>> ... Without something like suggested above or a computed goto on typeid
>> or Andrei's visitator, it almost pushes me to backout from using
>> variants and having to redesign around some common base class or
>> interface and using virtual function dispatch. :-(
>> 
>> 
> I see this sort of design in C all the time with event handling,
> although its with unions rather than discriminated unions, the same
> logic applies.
> 
> enum EventType {
>       Mouse,
>       Key,
>       Move,
>       ...
> }
> struct Event {
>       EventType type;
>       union {
>               MouseEvent mouse;
>               KeyEvent key;
>               MoveEvent move;
>               ...
>       }
> }
> 
> void dispatchEvent(const(Event)* event) {
>       ...
>       with(EventType) final switch(event.type) { case Mouse: ...
>       case Key: ...
>       case Move: ...
>       ...
>       }
>       ...
> }
> 
> That's the logic with standard unions, you should be able to get
> something similar with variants. It's more code to setup, but you end up
> with a simple jump table from the switch, and final in D makes it easy
> to change EventType without forgetting to update dispatchEvent.

Exactly, this is what I mentioned previously. Isn't it ugly compared to

  type Event = Mouse | Key | Move;

  void dispatchEvent(Event event) {
    match(event) {
      Mouse m => m.squeek();
      Key k => ...
      ...
    }
  }

What's with all the language proposals here? Why hasn't anyone proposed 
this before? This is in fact very helpful - that's why several modern 
languages have adopted it.

Reply via email to