IMHO, the test misses the point of compile-time metaprogramming: The
concept of "state" belongs to run-time. The D compile-time language is
purely functional and does not know a state or even an "order of execution".
The conditions "cannot die or be eaten twice" are, at their core, issues
of state. Any "solutions" that claim to catch one of the last three
errors must either go beyond the purely functional nature of the
compile-time language or rely on additional constraints (e.g. no reuse
of previous elements)
Of course, one could devise a language with non-functional compile time
features, but within D, this would fundamentally break the existing
concept of meta-programming.
On 09/27/2010 02:26 PM, bearophile wrote:
This is a harder variant of an old and very simple OOP problem:
http://merd.sourceforge.net/pixel/language-study/various/is-a-cow-an-animal/
The problem presents a hierarchy of types, some rules, and 11 tests, each one
of them represents a bug because it contains a violation of the rules. You have
to write the program in a way that the type system refuses as many of those 11
tests as possible at compile-time. There are many acceptable ways to write the
program, for example you may use functional programming, so you are able to
return different types, that enforce different rules, so it's not a contest,
it's more like a demonstration.
A basic Python implementation catches none of the 11 tests at compile time :-)
A basic D implementation that I have written catches five of the 11 bugs at
compile time:
http://ideone.com/87q67
I will try to write a more statically typed D version.
The site shows four C++ versions, the fourth is able to catch 8 of the 11 bugs
at compile-time. A type system that supports typestates is probably able to
catch all 11 bugs (because for example the Cow type has two states, alive and
eaten, and you can't perform some operations on a eaten cow, like eating it
again), but probably it's very hard to do this with D.
The fourth C++ version contains a line that I am am not even sure how to
translate to D (maybe there is a workaround with template constraints):
(void) static_cast<My_kind *>((Kind *) 0);
Bye,
bearophile