The upcoming C# 2.0 (as well as C++/CLI and VB.NET) has added a useful
facility to its template implementation to allow you to apply restrictions
on type parameters, called constraints. Here's an example:
class MyValue<T> where T : struct {
}
This tells the compiler only to instantiate MyValue for structs (and
primitive types such as int and long).
In D, we can already specialize templates based on type, but it would be
good to be able to extend specialization to restrict the type of type, so to
speak, perhaps similar to how the recently introduced IsExpressions work. At
compile time, the compiler would issue an error if code tries to instantiate
a template with a type that is not permitted by the template's (optional)
constraints. This facility would be useful, for example, if a template
relies on value semantics (ie, it expects a struct), or it relies on class
sematics (eg, it returns "null").
I think we can get away without adding any keywords to the language
(constraints-supporting .NET languages added "where"). The syntax might look
like this:
struct MyValue(T : struct) {
}
Other constraints allowed would include the same range allowed for
IsExpressions, eg:
template MyTemplate(T : class)
template MyTemplate(T : enum)
template MyTemplate(T : interface)
and so on. Another might be to enfore that the type has a default
constructor:
template MyTemplate(T : new())
Today I have to provide a default implementation of a template, and then
specialize it for types I don't want to allow. Constraints would do the
reverse, and would be an elegant addition.
Do people have ideas for how this might be done today, maybe with
IsExpressions? And do people think this is a good idea?
John.

The upcoming C# 2.0 (as well as C++/CLI and VB.NET) has added a useful
facility to its template implementation to allow you to apply restrictions
on type parameters, called constraints. Here's an example:
class MyValue<T> where T : struct {
}
This tells the compiler only to instantiate MyValue for structs (and
primitive types such as int and long).
In D, we can already specialize templates based on type, but it would be
good to be able to extend specialization to restrict the type of type, so to
speak, perhaps similar to how the recently introduced IsExpressions work.

I definitely agree, andI vaguely recall some mention from Walter that something
like this
is in the works. But I thought I'd chime in anyway.
In the Lux project (Lux is a concept-language that's been "in development" for
about as
long as D has, but without the ferverous community to drive it) we have this
kind of
specialization, based on "type attributes". A given template parameter can
specialize via
a "filter" that "requires", "includes", and "excludes" specified attributes.
(These
filters actually define attributes and can be applied to functions/methods as
well, for
customized protection.)
Example: for a template Foo that behaves differently for classes and structs,
and doesn't
want any other types, in Lux:
# define template Foo (
# filter(require(class)) symbol T
# ) {
# // do stuff
# }
#
# define template Foo (
# filter(require(struct)) symbol T
# ) {
# // do stuff
# }
Now, I don't neccessarily recommend the "filter" mechanism in D. I imagine
it'd be a load
of trouble to implement. However, I do think the "attributes" concept might
have some
validity. Maybe something like:
# // in D
# template Foo (alias T : class) {
# // do stuff
# }
#
# template Foo (alias T : struct) {
# // do stuff
# }
I figure '$' could be used as well, even though it has the other meaning of
"length of
current array". I don't see how this usage could possibly get confused with
that one, but
I suppose that might add a parsing quirk.
-- Chris Sauls

I definitely agree, andI vaguely recall some mention from Walter that
something like this is in the works. But I thought I'd chime in anyway.

That's good to hear.

In the Lux project (Lux is a concept-language that's been "in development"
for about as long as D has, but without the ferverous community to drive
it) we have this kind of specialization, based on "type attributes". A
given template parameter can specialize via a "filter" that "requires",
"includes", and "excludes" specified attributes. (These filters actually
define attributes and can be applied to functions/methods as well, for
customized protection.)
Example: for a template Foo that behaves differently for classes and
structs, and doesn't want any other types, in Lux:
# define template Foo (
# filter(require(class)) symbol T
# ) {
# // do stuff
# }
#
# define template Foo (
# filter(require(struct)) symbol T
# ) {
# // do stuff
# }
Now, I don't neccessarily recommend the "filter" mechanism in D. I
imagine it'd be a load of trouble to implement. However, I do think the
"attributes" concept might have some validity. Maybe something like:
# // in D
# template Foo (alias T : class) {
# // do stuff
# }
#
# template Foo (alias T : struct) {
# // do stuff
# }
I figure '$' could be used as well, even though it has the other meaning
of "length of current array". I don't see how this usage could possibly
get confused with that one, but I suppose that might add a parsing quirk.
-- Chris Sauls

I too would like to see custom attributes added to the language, ala Java's
new annotations. Wouldn't D need deeper RTTI or introspection to make custom
attributes useful? Otherwise I can't see how you'd apply attributes to user
code (C#, for instance, uses reflection to achieve this).