Kaz Kylheku a écrit :
The reason the solutions are huge in C++ templates, is that the C++ template
language is extremely clumsy. It's driven by declarations, and can fails to do
even some obvious inference. Classes have to be used in order to emulate
type-valued functions. If you want a function f:U, V -> T where U, V and T are
types, rather than values, then you can't just write a function. You have to
write a class, where the return value T is hacked as some member. And you
can't write a body of algorithmic code to compute that member; it all has to be
done in terms of templates: the class member which returns the function's
type-value is either just declared literally, or computed using calls
to other templates, which is very limited in terms of expressivity.
Things like if/else decisions all have to be coded as template classes.
Then you have to write reams of specializations for that class for various
instantiations of U and V. Oh yeah, and the C++ template system sometimes
doesn't even know when someting is intended to be a type, so you have to remind
it with ``typename''. The whole thing is the avoidance of giving the
programmer what is really needed: namely a compile-time meta-programming
language, in which you have functions and variables whose values are types and
pieces of syntax.
I developed a compiler that does exactly that. You have a library of
entry points into the compilation environment, where you can specify
templates in C. There are two types of paradigms:
1) Event oriented:
The compiler generates a stream of compilation events that you can
subclass, in a similar way as GUI event oriented programming where
the GUI generates events that you subclass.
The types of events are:
begin/end compilation
begin/end function
begin/end statement
Syntax error (here you add syntax as you wish)
etc (many others omitted)
2) Template oriented:
You define a compile time function that resides in some dynamic
library, and you call it from your program. For instance you
define a function "list" that will generate a list type, and
you call it with
list<int>
That function will generate a type definition.
All code generation is based in a text interface: in All cases, the
generated code is a text stream. That text can contain further templates
that will provoke other events. When an event is active however, the
system will never generate an event for the event that is currently
running.
Now, this would need an army of people to do that, and I am alone.
The C++ template system is the work of people who are so gifted that they don't
think they have to study the computer science which came before them.
Look at, say, Template Haskell. There we don't have the huge algorithmic
solution sets of STL and BOOST. (Much of what C++ templates do doens't
even need the TH extension, just the straight language).
Speaking of which, I'm now revisiting the TH paper
(
http://www.haskell.org/th/papers/meta-haskell.ps) and have noticed it has some
juicy things to say about C++ templates, in section 10.1, which is mostly
praise for C++ templates, but also this:
``It is (now) widely recognized that this type-system computation language
[of C++ templates] is simply an extraordinarily baroque functional language,
full of /ad hoc/ coding tricks and conventions.''
Bingo!
In my system you *can* do assignments, since everything is programmed in
C. You can save context from an event into the next, for instance just
to gather statistics, etc.
jacob