Boost logo

Proto :

Subject: Re: [proto] Problems with unary function node
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2011-10-28 09:29:09


On 28/10/2011 07:30, Eric Niebler wrote:

> Regardless, I'm convinced that a complete fix is possible, and I have it
> mostly coded. It would require you (the user) to disable unary function
> and assign in your domain via a grammar. But. It's expensive at compile
> time, and everybody pays. I need to be convinced before I proceed.

I think it would also be fine to just document the issue, and let people
special-case the generator if needed.

I wouldn't want all Proto-based code to become slower just because of this.

I would be quite interested to see what the fix is, though.

> Your
> example code was very contrived. (Certainly you don't need to ask a
> Proto expression extension type whether it is a proto expression. The
> answer will always be yes.)
> So what is your realistic usage scenario?
> What type categorization do you want to do on the extension type that
> you can't do on the raw passed-in expression?

The call goes through generic components that don't necessarily deal
with Proto expressions, but some of them may have special
specializations for Proto expressions.

The categorization of non-raw expressions is of course richer, because
each of those went through their own generators and attached special
semantic information to each node type.

In NT2, we generate expressions that look like this

template<class Expr, class ResultType>
struct expression
   : proto::extends< expression<Expr, ResultType> >
{
     typedef typename extent_type<ResultType>::type extent_type;

     expression(Expr const& expr, extent_type const& extent_)
       : proto::extends< expression<Expr, ResultType> >(expr)
       , extent(extent_)
     {
     }

     extent_type const& extent() const { return extent; }

private:
     extent_type extent;
};

It not only wraps the naked Proto expression, but it also contains what
the expression represents from a logical point of view (at some point we
wanted to use domains for this, but it's just not practical).
The expression also contains its logical size, which is computed at
runtime by the generator, and is tightly coupled with what the
expression represents.

So we categorize a naked tag(a0, a1) expression as
expr_< unspecified_<Expr>, domain, tag >

The same expression with the result type information of int32_t is
expr_< scalar_< int32_<Expr> >, domain, tag >

In certain situations, I ended up with a category of unspecified_<Expr>
on some of my expression types because the categorization meta-function
was instantiated on an incomplete type (the expression type for the
terminal).
This way quite unexepcted and hard to debug.

Regardless, we like to have to ability to inject specializations *after*
the expression type has been defined, which only works if instantiation
is delayed until the function is actually called.


Proto list run by eric at boostpro.com