
Boost : 
Subject: Re: [boost] [contract] concepts: pseudosignatures vs. usage patterns
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 20121013 17:40:15
>
> > This is how I
> > understand the issue you describe:
> >
> > We have a concept requirement like this:
> >
> > concept Operation<typename Op, typename T>
> > = requires(Op op, T t)
> > {
> > //...
> > bool = { op(t) }; // "convertible to bool"
> > }
>
> I have to admit that I'm not entirely familiar with the newfangled
> syntax being proposed, but I think I can muddle through your use of it
> here. Operation<Op,T> says that declval<Op>()(declval<T>()) is
> valid and convertible to bool, right?
>
Right.
>
> > We have the following function template
> >
> > template< typename Op, typename T >
> > requires Operation<Op, T>
> > bool fun(Op op, T t) {
> > return true && op(t);
> > }
> >
> > We have a following concrete type that models Operation:
> >
> > class FunnyBool{...}; // almost like bool
> > class X{...}; // which will become T
> > FunnyBool operation(X x) {...}; // which will become Op
> > bool operator&& (bool a, FunnyBool b) {}; // which will do some
> unexpected
> > thing
>
> Yes, you're on the right track here...
>
> > When we instantiate:
> >
> > fun(operation, X{});
> >
> > which operator&& will be picked? (bool, bool) or (bool, FunnyBool)?
> >
> > This is the question you ask.
>
> Well, I'm not sure that my entire concern can be captured in this one
> example, but this question is certainly an instance of my concern.
>
> > Am I right? If so, the answer I find the most logical would be is
> > since the concept is only aware that the type is convertible to bool
> > and can only rely on this information, when function fun() is
> > instantiated with operation and X, it only sees a restricted version
> > of operation and X and indirectly FunnyBool as though 'through concept
> > Operation' and must convert FunnyBool to bool before applying operator
> > &&.
>
> That's what the pseudosignature approach does, so you and I agree on
> that much.
Yes. I would expect that either approach is capable of doing the same.
> In fact, these are the "loose match" semantics you were
> objecting to earlier. :)
I was not objecting to "loose match". I was trying to say that
pseudosignatures look like normal signatures and might imply that no
"loose match" occurs. In contrast, usage patterns look like expressions,
and you do expect implicit conversions. Although, I do not find it a major
argument against pseudosignatures.
> Notationally speaking, I think
> pseudosignatures are *much* more suggestive of those semantics than are
> valid expressions.
>
Could you show an example where this is the case? I may be missing
something obvious, but I would say it is the other way around.
>
> The bigger problem is that the valid expression approach also makes it
> possible/easy to specify requirements where the type corresponding to
> bool in this example is never explicitly named, e.g.:
>
> bool = { true && op(t) };
>
> value_type = { *it++ };
>
> etc. IIUC these sorts of things cause big problems for typechecking
> (exponential explosions?) and usability, but I'd have to defer to others
> to describe in detail what those issues are.
>
> > Of course this is achievable only in concepts as language feature. Any
> > usepatternbased concept library will not be able to implement this
> > behavior, as far as I am aware.
>
> On the other hand, a pseudosignaturebased library conceivably could.
>
And since this discussion started because Lorenzo wonders which of the two
approaches to take for his library, perhaps this limitation gives us the
answer.
Regards,
&rzej
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk