Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost-users][[proto] : Seeking advice on a DSL
From: Eric Niebler (eric_at_[hidden])
Date: 2010-03-18 19:23:42


On 3/19/2010 7:09 AM, Manjunath Kudlur wrote:
>>> Thanks, that does help. The other approach I was toying with was to
>>> hold the values "in situ", i.e., make int_ contain the datum.
>>
>> I don't see how. When you create your "program", the data are not yet
>> available. They are only supplied later when you are ready to execute your
>> "program".
>> I must be misunderstanding what you're suggesting.
>
> Sorry, I should have been clearer. My suggestion was to make
> program_variable look like this.
>
> template<typename T>
> struct program_variable {
> T value;
> };
>
> And in the operator(..) function of program_expr, copy the parameters
> to the values like so:
> proto::value(proto::left(proto::left(proto::left(*this)))).value = a0;
> proto::value(proto::left(proto::right(proto::left(*this)))).value = a1;
> Then call program_eval()(*this), then copy back to a0 and a1.

OK, I see. There are 2 problems with this. One is fixable. The other
isn't, but it may not be an issue depending on your use case. See below.

>> They shouln't, unless your generator is doing something extra.
>
> You are right, I spoke too soon. I am attaching the code I wrote with
> in situ storage, based on the code you sent. And it seems to work. I
> like the idea of in place storage because everything is nicely
> packaged up in the expression object. No need for extra maps and
> vectors.

Right.

> Also, using the other way, handling different types becomes a
> problem. What if I want Program(&a, b) where a is int_ and b is
> double_.? In place storage just has the right type already.

Right.

> Please do
> let me know if you spot some inelegance or any other problem with this
> approach.

That is an interesting approach. The two problems I see are:

1) Your use of BOOST_AUTO leaves a bunch of dangling references and
creates undefined behavior. As you have it defined, program_generator no
longer has the effect of deep-copying the expression tree. Try
displaying typeid(p).name() and see, for instance, that the intermediate
expressions are stored by reference, and the literal 2 is stored by int
const&. Any attempt to use p will likely expode sooner or later. The fix
is to deep-copy the expression when you wrap it in program_expr, but a
simple deep-copy will break your scheme because every program_variable
will be deep-copied too. A simple fix would be to make
program_variable<T> a wrapper for a boost::shared_ptr<T>, but ...

2) Your program objects are not thread safe. Since they contain mutable
data, you can't stick the program in, say, a boost::function, make a few
copies and evaluate them concurrently within different threads. That may
not be important to you, but I consider it a pretty serious shortcoming.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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