Boost logo

Boost Users :

From: Joel de Guzman (joel_at_[hidden])
Date: 2008-01-09 20:33:20


Tobias Schwinger wrote:
> Joel de Guzman wrote:
>> Tobias Schwinger wrote:
>>> Stjepan Rajko wrote:
>>>> * What is your evaluation of the design?
>>> I very much like the simplicity.
>>>
>>> I'm not sure it really suits the name 'switch_', as I'd expect something
>>> syntactically different (something like Joel sketched out in his review,
>>> and with some argument forwarding), however, I think it's an important
>>> building block that should be kept as simple as possible.
>> I can assure you that my suggestion is "as simple as possible, but
>> not simpler" ;-) Simpler than that is simply not usable to me.
>> I know. I've been there many times. I have real world use cases
>> for this thing. Switch is not simple. Let's not pretend it is.
>
> My point is that the utility we have here is in fact too different from
> phoenix::switch_ to compare the two (and that boost::switch_ is not the
> best name):

Maybe.

> What would be the point in phoenix::switch_ if it wasn't lazy?

Good point!

IIUC, what you mean is: what's the advantage of this:

      switch_<return_type>(n,
          case_<1>(f1),
          case_<2>(f2),
          case_<3>(f3),
          default_(fd)
      );

vs. using a plain switch:

      switch (n) {
          case 1: f1(); break;
          case 2: f2(); break;
          case 3: f3(); break;
          default: fd;
      };

?

In a word, composability. You can compose the first, but not the
second. Ok, that seems wrong in my syntax ('twas just a sketch :-)
Perhaps:

      switch_<return_type>(n)
      (
          case_<1>(f1),
          case_<2>(f2),
          case_<3>(f3),
          default_(fd)
      );

Oughta do it. Did that clear things up?

> As Steven pointed out, overloading operator() (which is roughly what you
> propose - just using an uglier syntax) is a rare use case. Usually we'll
> want to feed the index to some metaprogramming machinery and instantiate
> several high-speed dispatched control paths.

It can amount to the same thing if we allow the cases:

     case<1>(f1), case<2>(f2), ... case<N>(fN)

to be a fusion sequence.

> This utility is about generating the machine code of 'switch'. It does
> not necessarily have to mimic it's syntax!

Why not? Syntax matters! And again, it's not just syntax. Why
limit yourself to a not-really-a-switch-but-similar library when
you can have a real-switch library with all the possibilities
that switch can provide -- fallback, individual functions,
defaults, etc.

>> Here's an acid test for the API -- try to implement my suggested
>> syntax on top of the "simple" API. You'll soon realize that you
>> can't
>
> No?! Here is how it's done:
>
> o Use fusion::unfused or wire up some operators to build a fusion::map
> of constant / function object pairs, and
>
> o create a function object from that map that looks up the appropriate
> function object in the map and calls it (if we want it to be non-lazily
> evaluated) or returns it (otherwise) and is fed to 'switch_'.

Ok, indeed you can. Man, I sometimes forget about this
thing called Fusion.

> Please note that the reverse requires indeed to repeat the PP code.

What reverse?

> Also note that it would also work to implement the variant visitor.

Indeed.

> Also also note that the 'switch_' name is obviously confusing :-).

Because the API *is* confusing. Why invent another scheme
when we can mimic a well-proven, time-tested mechanism,
albeit with an FP flavor --To me, that's most important:
the possibility of using higher order functions in the cases.

I'll leave this as-is for now. Let me ruminate on this some more.
I'll try to come up with a better suggestion refining my first.

Regards,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net