Thread overview
Interfaces and Template Specializations
Jan 10, 2009
Björn T. Herzig
Jan 10, 2009
dsimcha
January 10, 2009
Hi,

I've been trying out D lately and stumbled upon the following problem.

I have 2 interfaces:

interface Plugable
{
	public void plug();
}

interface Printable
{
	public void print();
}

and two classes that implement those named Test which implements Plugable and Printable, and Test2 which only implements Plugable.

I now want to create a generic function with two specializations.

void tester(U)(U u) if (is(U : Plugable) && is(U : Printable))
{
	writefln("U : Printable, Plugable");
	u.plug();
	u.print();
}

void tester(U : Printable)(U u)
{
	writefln("U : printable");
	u.print();
}

First of all this doesn't compile with the dmd 2.014 compiler since it doesn't accept the if statement after the template declaration (Or did I do something wrong?). Another thing is that it's really weird syntax. In the second specialization it's enough to write U : Plugable but it's not possible to write something like void tester(U : Printable, Plugable)(U u) since Plugable would be handled as a second template parameter (or am I mistaken?). Wouldn't it be much nicer if you could write something like this : void tester(U : (Plugable, Printable))(U u) and void tester(U : (Plugable))(U u)? This way it would be possible to use a unified syntax for both cases without the need for a special case with the if-statement.

Btw, are there plans to port dmd to Solaris/OpenSolaris? Since it's my main OS i would really like to use D on that platform.

Regards,
Björn
January 10, 2009
== Quote from Björn_T._Herzig (raichoo@googlemail.com)'s article
> Hi,
> I've been trying out D lately and stumbled upon the following problem.
> I have 2 interfaces:
> interface Plugable
> {
> 	public void plug();
> }
> interface Printable
> {
> 	public void print();
> }
> and two classes that implement those named Test which implements Plugable and
Printable, and Test2 which only implements Plugable.
> I now want to create a generic function with two specializations.
> void tester(U)(U u) if (is(U : Plugable) && is(U : Printable))
> {
> 	writefln("U : Printable, Plugable");
> 	u.plug();
> 	u.print();
> }
> void tester(U : Printable)(U u)
> {
> 	writefln("U : printable");
> 	u.print();
> }
> First of all this doesn't compile with the dmd 2.014 compiler since it doesn't
accept the if statement after the template declaration (Or did I do something
wrong?).

http://digitalmars.com/d/2.0/changelog.html#new2_015

This syntax is called constraints.  It didn't exist before 2.015.  The info on some pages is outdated.  The latest DMD version is 2.023.

> Another thing is that it's really weird syntax. In the second
> specialization it's enough to write U : Plugable but it's not
> possible to write something like void tester(U : Printable, Plugable)(U u) since
Plugable would be handled as a second template parameter (or am I mistaken?).
Wouldn't it be much nicer if you could write something like this : void tester(U :
(Plugable, Printable))(U u) and void tester(U : (Plugable))(U u)? This way it
would be possible to use a unified syntax for both cases without the need for a
special case with the if-statement.

The weird syntax is because the first case is a constraint and the second is a template specialization.  For consistency, it might be better to just use constraints for everything.

Overall, though, D2's compile-time reflection system grew very organically and has a lot of duplicated features.  There's been some discussion in the past about how to reduce this complexity by removing redundancy.  You may have stumbled on one here:  Constraints, as far as I can tell, are just a more general case of template specialization.  Maybe we don't need template specialization anymore.
January 10, 2009
On Sat, Jan 10, 2009 at 5:40 PM, dsimcha <dsimcha@yahoo.com> wrote:
> Overall, though, D2's compile-time reflection system grew very organically and has a lot of duplicated features.  There's been some discussion in the past about how to reduce this complexity by removing redundancy.  You may have stumbled on one here:  Constraints, as far as I can tell, are just a more general case of template specialization.  Maybe we don't need template specialization anymore.

Not to hijack the thread, but yes - we no longer need template
specialization.  But we don't necessarily need to kill the syntax,
since "template Foo(T: int) {}" is certainly shorter than "template
Foo(T) if(is(T: int)) {}".  Simply rewrite the former as the latter,
problem solved.