Ducks
Chris Williams
yoreanon-chrisw at yahoo.co.jp
Wed Feb 5 17:01:57 PST 2014
I found some old threads about the concept of "static interface":
http://forum.dlang.org/thread/20091116172513.GB13817@llucax.com.ar
I agree that using template checks to validate compilability is
more flexible than interface definitions, specifically because
you can create cross-compatibility between functions and
properties or allow for undefined types. However, I think that
template checks have two large flaws:
1. You only know what the target is that you have to hit by
looking at their source. Or, the person who wrote the template
checker needs to, effectively, rewrite their check as a document
comment. (E.g. see std.range isInputRange)
2. Writing functions which are restricted to a particular type is
long-winded and subsequently error-prone. (E.g. all
implementations of std.random uniform() should check
isUniformRNG(), when they accept an external generator)
I think that the advantages that are added by template-based
compilability checks can be gained without losing flexibility if
we add a more lenient interface definition, like:
duck InputRange {
bool empty; // can be a function or not. Doesn't care. Anyone
using it must avoid using () syntax
auto front; // Doesn't care what the return type is so long as
it's non-void
void next; // Cannot return a value
}
While a "duck" would allow one to define methods with explicitly
typed parameters and return types like:
duck IntStack {
void push(int value); // must accept an int
int pop(); // must be a method that returns an int
}
It's easy and preferred to define ducks with the greatest
flexibility.
Since these would still be a feature of the templating system, I
might recommend using them like:
void foo(Range : InputRange)(Range r) {
...
}
Rather than:
void foo(InputRange r) {
...
}
It's still a little bit verbose, but it would help people to
notice that ducked parameters are available at compile-time only.
And since these would be an official part of the language, DDoc
would generate a public definition of the type target, like it
does with interfaces.
I would also suggest a further version of ducks, for things like
this:
duck Integral if (is(Integral : int)); // not a particularly good
check
Thus allowing code like:
void foo(Int : Integral)(Int i) {
...
}
These wouldn't be quite as self-documenting, but I think would
allow the general collapse of type specialization into the type
specialization field.
More information about the Digitalmars-d
mailing list