Another day in the ordeal of cartesianProduct

H. S. Teoh hsteoh at quickfur.ath.cx
Sat Oct 27 09:21:44 PDT 2012


On Sat, Oct 27, 2012 at 09:06:11AM -0400, Andrei Alexandrescu wrote:
> On 10/27/12 8:23 AM, Peter Alexander wrote:
> >Yeah, it's certainly not going to be easy. It's unfortunate that D
> >adopted the whole C++ style "glorified macros" approach to templates
> >-- it makes it very difficult to reason about (or automate reasoning
> >about) the semantics of your code.
> 
> I think D has reached a sweet spot with restricted templates.
> 
> >Retrofitting some sort of structure to templates will be a Herculean
> >task, but I think it has to happen. It is clear to me that the
> >development process we use now (write the template, try a few
> >instantiations, pray) is unsustainable beyond simple templates.
> 
> It's not clear to me at all. The mechanism works very well and is more
> expressive than alternatives used by other languages.
[...]

I think the complaint is that the template constraints enforce ducktype
requirements on the *caller*, but not on the template code itself.
That's what Peter's example was about: the signature constraint declares
that the template takes an input range, yet the template body makes use
of non-input range properties of the argument.

I think there is some merit to being able to declare concepts; for
example:

	// This concept matches any type that has fields that satisfy
	// what's specified inside the body.
	concept InputRange(T) {
		bool empty;	// this matches @property bool empty() too
		T front;
		void popFront();
	}

	auto myRangeBasedFunc(InputRange r) {
		r.popBack();	// compile-time error: InputRange does
				// not define .popBack
	}

This way, *both* the user of the template and the template writer are
kept "honest" (i.e., they both have to conform to the requirements of an
input range). The compiler can thus statically check the template for
correctness *before* it ever gets instantiated.

Not only so, the compiler will be able to generate a meaningful error
message when the templates fail to match -- it can tell the user "the
template didn't match 'cos struct X that you tried to pass to it isn't
an InputRange, nor a ForwardRange, ... etc.".

Currently, if the template writer screws up, the compiler doesn't know
any better, and only when the user actually tries to pass something that
the template body can't handle, does the error manifest itself. Which
seems a bit late -- it should be the template writer who first notices
the problem (like if the compiler can statically verify the template
body and complain loudly before the code ever gets to the user). Plus,
the error message is usually a long cryptic sequence of instantiation
failures containing all sorts of internal Phobos types that the user has
no idea about. The compiler can hardly do much better, because it
doesn't have enough information to make a meaningful message.


T

-- 
Старый друг лучше новых двух.


More information about the Digitalmars-d mailing list