Template constraints in D
Bill Baxter
dnewsgroup at billbaxter.com
Sat Jun 21 16:12:50 PDT 2008
Walter Bright wrote:
> Bill Baxter wrote:
>> A more natural way to declare required functions would be nice.
>>
>> First of all, about the isAddable example, can't you just use T.init
>> instead of writing an anonymous delegate? Like
>> __traits(compiles, T.init + T.init)
>
> I think you're right.
>
>> Anyway, for a less trivial example I think that becomes pretty
>> cumbersome. E.g.:
>>
>> concept Stack<typename X> {
>> typename value_type;
>> void push(X&, const value_type&);
>> void pop(X&);
>> value_type top(const X&);
>> bool empty(const X&);
>> };
>>
>> is going to translate to something like this?:
>>
>> template Stack(T)
>> {
>> const Stack =
>> is(T.value_type) &&
>> __traits(compiles, (T t, T.value_type v) { push(t, v); }) &&
>> __traits(compiles, (T t) { pop(t); }) &&
>> __traits(compiles, (T t) { top(t); }) &&
>> is(typeof(top(T.init))==T.value_type) &&
>> __traits(compiles, (T t) { empty(t) }) &&
>> is(typeof(empty(T.init))==bool);
>> }
>>
>> I hope you can work out a way to give this a more natural syntax, like
>> Concepts will have in C++0x.
>
> You're the first I've heard say that Concepts have a natural syntax!
Well, I didn't go very far into that spec document you link to, but I
think the Stack example above (which I took from there) is really
straightforward. It looks just like a kind of interface declaration.
Since concepts are trying to express compile-time interfaces, that makes
plenty of sense.
> But let me try:
>
> template Stack(T)
> {
> const Stack =
> __traits(compiles,
> (T t)
> { T.value_type v = top(t);
> push(t, v);
> pop(t);
> if (empty(t)){}
> });
> }
>
> The idea is that the desired operations are expressed as operations,
> rather than as function signatures.
I do like the idea -- show the actual code you want to work, not
something one-step removed like "has an opAdd member". Still, anything
containing __traits looks like an afterthought.
Also, I'm not sure how it's going to work in C++, but isn't the compiler
going to have a hard time reporting errors in that kind of thing?
Failure to instantiate could be because of a very minor typo in the big
list of constraints.
I'm not sure how C++ will deal with that, but I think it's another place
where concept maps help. They introduce a little redundancy. They give
you a place to say "I think type X satisfies concept Y, and here's how".
That gives the compiler a place to say, "No you're wrong, type X does
not satisfy concept Y because Foo isn't actually a method of X". It
seems like it should be possible to generate very readable error
messages from that.
>> An unrelated comment is that I don't think it is relevant or
>> respectful to compare the lengths of the specs. The spec for Concepts
>> that you link to includes many many more in depth examples than the D
>> spec does. It's an apples vs oranges comparison. So 5 pages vs 49
>> pages really doesn't have much meaning at all.
>
> I wished to make the point that D constraints build on what one already
> knows - how to write a D expression. Concepts, on the other hand, have a
> major new syntax and semantic thing that must be learned. Perhaps I
> expressed the point badly, do you have a suggestion?
I think the number of new keywords expresses that well enough. You
could also add something like "new syntactic constructs: 1 vs [however
many concepts add]". I think you can pretty much count up the gray
boxes in the Concepts spec to get that number. Or maybe call it "new
productions added to grammar".
--bb
More information about the Digitalmars-d
mailing list