boost::proto, improving error handling

I don't know if something can be done, but it would have saved me quite some time. Here what happened: - I was moving my small example to a more realistic case. As ususal, example works and reality doesn't care. - In the example I had terminal<number<_,_> > and all was kosher. I tried to add a template parameter with a default value, just to make sure I could still have patterns with all arguments and everything was fine. - now in reality my number has 6 template arguments. 6 is larger than 5, and with this I've given out what happened, at least to Eric. For others, 5 is the default maximum number of arguments in proto expressions. So far, so good. The problem is that my grammar had a pattern terminal<number<_,_,_,_,_,_> >. I don't know if it is possible to make proto complain hard and loud about building a pattern (or other expressions) with more arguments than the maximum allowed by configuration, but in my case the pattern was not matching causing my expressions to be invalid. And the error from GCC was nothing hinting at grammars, matches or anything. It was just saying that overloads for operators where ambiguous (because of my operator int and unsigned int, I don't know what it would have happened without). And I think that 6 is a better default value for the number of allowed arguments. Just kidding, as long as defining it before including proto headers is officially blessed and documented, I'm ok. Another nice thing to have, although I would only put it in if very easy to code: especially in presence of default parameters it might be nice to have a pattern matching "the rest of the argument list". Something like a proto::___. Cheers, Maurizio

Maurizio Vitale wrote:
- now in reality my number has 6 template arguments. 6 is larger than 5, and with this I've given out what happened, at least to Eric. For others, 5 is the default maximum number of arguments in proto expressions.
So far, so good. The problem is that my grammar had a pattern terminal<number<_,_,_,_,_,_> >. I don't know if it is possible to make proto complain hard and loud about building a pattern (or other expressions) with more arguments than the maximum allowed by configuration, but in my case the pattern was not matching causing my expressions to be invalid.
I don't think there is anything I can do. To detect a template with a too-high arity, I'd need specializations with at least that arity. And if I have an arity-6 specialization, why not make it do the right thing instead of reporting an error? There needs to be a cut-off somewhere, beyond which things will break mysteriously. I don't know if template varargs will improve this situation, but I hope so. (I'd need a template-template vararg.)
And I think that 6 is a better default value for the number of allowed arguments. Just kidding, as long as defining it before including proto headers is officially blessed and documented, I'm ok.
It is. #define BOOST_PROTO_MAX_ARITY 6 should do the trick.
Another nice thing to have, although I would only put it in if very easy to code: especially in presence of default parameters it might be nice to have a pattern matching "the rest of the argument list". Something like a proto::___.
Well, double-underscores are off-limits to user code, according to the standard. But maybe you'd like something like: std::basic_string< vararg<_> > to be the equivalent of std::basic_string< _, _, _ > It doesn't seem like a big win to me, and it wouldn't solve the template arity problem you ran into. -- Eric Niebler Boost Consulting www.boost-consulting.com

Eric Niebler <eric@boost-consulting.com> writes:
I don't think there is anything I can do. To detect a template with a too-high arity, I'd need specializations with at least that arity. And if I have an arity-6 specialization, why not make it do the right thing instead of reporting an error?
If it has the same weight in terms of compilation time, of course. I thought that maybe there was a cheaper way to detect the error, like a specialization with some large number of default arguments that kicks in only above BOOST_PROTO_MAX_ARITY and is not even defined, so that you get an error. If it is not possible/desirable then the limit should be spelled out in the documentation, both as a general rule and in the section on grammars, as it might not be obvious to the newcomer that BOOST_PROTO_MAX_ARITY applies to patterns as well.
And I think that 6 is a better default value for the number of allowed arguments. Just kidding, as long as defining it before including proto headers is officially blessed and documented, I'm ok.
It is. #define BOOST_PROTO_MAX_ARITY 6 should do the trick.
I know it works, but I don't think is in the documentation.
Another nice thing to have, although I would only put it in if very easy to code: especially in presence of default parameters it might be nice to have a pattern matching "the rest of the argument list". Something like a proto::___.
Well, double-underscores are off-limits to user code, according to the standard.
Rats!
But maybe you'd like something like:
std::basic_string< vararg<_> >
to be the equivalent of
std::basic_string< _, _, _ >
It doesn't seem like a big win to me,
Well if it has to be that long, certainly not. What about _n or _s? [the first would stay for N copies and the second for the plural of _] or _*_ if one wants to get creative w/ operators. The main question for me is whether it is hard to code and whether it would impact the long term maintainability of the library. If it is easy we can found a short name for it (actually I'm not sure that _s is valid, although I believe it is). Also, imo, to be useful shouldn't stay for "all the arguments", but rather for "all the arguments that haven't been mentioned", so std::basic_string<char,_s> would also be valid (and mean std::basic_string<char,_,_> ). No idea whether this is doable.
and it wouldn't solve the template arity problem you ran into.
Clear. It is just that I thought of it while writing that mail and was too lazy to start a new thread. Sorry.

Maurizio Vitale wrote:
Eric Niebler <eric@boost-consulting.com> writes:
I don't think there is anything I can do. To detect a template with a too-high arity, I'd need specializations with at least that arity. And if I have an arity-6 specialization, why not make it do the right thing instead of reporting an error?
If it has the same weight in terms of compilation time, of course. I thought that maybe there was a cheaper way to detect the error, like a specialization with some large number of default arguments that kicks in only above BOOST_PROTO_MAX_ARITY and is not even defined, so that you get an error.
I doubt it would be less expensive to merely detect the error than to handle it correctly. A thought. BOOST_PROTO_MAX_ARITY is primarily for controlling how many children a node in an expression tree is allowed to have. There's no good reason to tie it to the max arity of templates that proto::matches<> can handle. There should be a separate constant for that, and perhaps it could default to something higher than 5.
If it is not possible/desirable then the limit should be spelled out in the documentation, both as a general rule and in the section on grammars, as it might not be obvious to the newcomer that BOOST_PROTO_MAX_ARITY applies to patterns as well.
Totally agreed.
And I think that 6 is a better default value for the number of allowed arguments. Just kidding, as long as defining it before including proto headers is officially blessed and documented, I'm ok.
It is. #define BOOST_PROTO_MAX_ARITY 6 should do the trick.
I know it works, but I don't think is in the documentation.
Yep, the docs are currently lacking.
Another nice thing to have, although I would only put it in if very easy to code: especially in presence of default parameters it might be nice to have a pattern matching "the rest of the argument list". Something like a proto::___.
<snip>
What about _n or _s? [the first would stay for N copies and the second for the plural of _] or _*_ if one wants to get creative w/ operators. The main question for me is whether it is hard to code and whether it would impact the long term maintainability of the library. If it is easy we can found a short name for it (actually I'm not sure that _s is valid, although I believe it is).
Also, imo, to be useful shouldn't stay for "all the arguments", but rather for "all the arguments that haven't been mentioned", so std::basic_string<char,_s> would also be valid (and mean std::basic_string<char,_,_> ). No idea whether this is doable.
Doable, but not trivially. In all likelihood it'll make proto::matches<> compile slower in the general case. My gut feeling is that this feature isn't worth the trouble. -- Eric Niebler Boost Consulting www.boost-consulting.com
participants (2)
-
Eric Niebler
-
Maurizio Vitale