D has introduced a pretty cool tool: templates. These are
basically namespaces that can be instantiated by a type/alias.
Mixing with them the notion of "eponymous" allows to do some
seriously cool things with them.
One of the things I find strange though is that they *must* be
parameterized. This limitation seems entirely artificial to me.
Why not allow templates without parameters, just the same way
some functions aren't parameterized. There are useful use-cases
for this:
* Simple creation of namespaces (as opposed to non-contructible
struct/classes)
* Allows creating private helpers, without polluting the rest of
the module (private functions are still callable by other
functions in the module).
So... yeah, why don't we have this?
--------
Related: I have encountered this problem, and I can't seem to
work around it; *other* than non-parameterized templates.
Basically, I have this pred function, we'll call it "foo". This
pred function can itself be parameterized to take its own
(optional) pred. This basically allows:
foo(a, b)
or
foo!pred(a, b)
This is "traditionally" solved by doing:
void foo(A, B)(A a, B b);
void foo(alias pred, A, B)(A a, B b);
Here is the kicker though: "foo" is itself a pred. This means
that I *need* to be able to pass "foo!pred" as a predicate. This
does not work, as "foo!pred" is nothing: The compiler doesn't
know what you are talking about, as the parameters A and B are
missing. This is usually solved by a template:
template foo(alias pred)
{
void foo(A, B)(A a, B b);
}
This works.... *however* the presence of the "void foo(A, B)(A a,
B b);" confuses the crap out of the compiler:
foo(a, b); //OK
alias PRED = foo!"hello";
PRED(a, b); //OK
BUT:
foo!"hello"(a, b); //Error:
Error: template hello.foo does not match any function template
declaration. Candidates are:
hello.foo(R1, R2)(R1 r1, R2 r2)
hello.foo(alias pred)
Error: template hello.foo(R1, R2)(R1 r1, R2 r2) cannot deduce
template function from argument types !("hello")(int, int)
Error: template instance foo!"hello" errors instantiating template
So... how to make this work? AFAIK, non-parameterized templates
should solve it. Or is it just a compiler issue?
FYI: This is a problem present in Phobos. You can use:
"equal!equal(RoR1, RoR2)"
To compare two ranges of ranges. equal!equal gets instanciated,
because the args are present to "finish" the missing R1/R2 args
after pred.
However, this neat trick stop there:
"equal!(equal!equal)(RoRoR1, RoRoR2)"
This time, this does not work, as the compiler can't resolve the
predicate.
I'd like to solve this. IMO "equal!equal" is one of the neatest
"1-word" in D, and I want to make sure it works as one would
expect it to.
--------
So: Any workaround recommendations? Alternatives? Thoughts on
parameter-less templates (regardless of my issue)?

D has introduced a pretty cool tool: templates. These are basically
namespaces that can be instantiated by a type/alias. Mixing with them
the notion of "eponymous" allows to do some seriously cool things with
them.
One of the things I find strange though is that they *must* be
parameterized. This limitation seems entirely artificial to me. Why not
allow templates without parameters, just the same way some functions
aren't parameterized. There are useful use-cases for this:
* Simple creation of namespaces (as opposed to non-contructible
struct/classes)
* Allows creating private helpers, without polluting the rest of the
module (private functions are still callable by other functions in the
module).
So... yeah, why don't we have this?

D has introduced a pretty cool tool: templates. These are
basically namespaces that can be instantiated by a type/alias.
Mixing with them the notion of "eponymous" allows to do some
seriously cool things with them.
One of the things I find strange though is that they *must* be
parameterized.

Yes and no.
void foo()() {} is a parameter-less template.
As the construct already exists at semantic level, I guess making
it available everywhere is the way to go.

D has introduced a pretty cool tool: templates. These are
basically namespaces that can be instantiated by a type/alias.
Mixing with them the notion of "eponymous" allows to do some
seriously cool things with them.
One of the things I find strange though is that they *must* be
parameterized.

Yes and no.
void foo()() {} is a parameter-less template.
As the construct already exists at semantic level, I guess
making it available everywhere is the way to go.

I think strictly speaking, that is a "parameterless parameterized
function", as opposed to a "non parameterized function".
In regards to template (I mean the actual "template"), I guess I
wish we could either:
1. Allow non-parameterized templates (eg template foo {...})
2. Allow invoking a template without parameters (provided the
template has 0 parameters, or default parameters), without doing
"!()"
But yeah, I think I agree with you, that it should be made
available everywhere.

Related: I have encountered this problem, and I can't seem to work around
it; *other* than non-parameterized templates. Basically, I have this pred
function, we'll call it "foo". This pred function can itself be
parameterized to take its own (optional) pred. This basically allows:
foo(a, b)
or
foo!pred(a, b)
This is "traditionally" solved by doing:
void foo(A, B)(A a, B b);
void foo(alias pred, A, B)(A a, B b);
Here is the kicker though: "foo" is itself a pred. This means that I
*need* to be able to pass "foo!pred" as a predicate. This does not work, as
"foo!pred" is nothing: The compiler doesn't know what you are talking
about, as the parameters A and B are missing. This is usually solved by a
template:
template foo(alias pred)
{
void foo(A, B)(A a, B b);
}
This works.... *however* the presence of the "void foo(A, B)(A a, B b);"
confuses the crap out of the compiler:
foo(a, b); //OK
alias PRED = foo!"hello";
PRED(a, b); //OK
BUT:
foo!"hello"(a, b); //Error:
Error: template hello.foo does not match any function template
declaration. Candidates are:
hello.foo(R1, R2)(R1 r1, R2 r2)
hello.foo(alias pred)
Error: template hello.foo(R1, R2)(R1 r1, R2 r2) cannot deduce template
function from argument types !("hello")(int, int)
Error: template instance foo!"hello" errors instantiating template
So... how to make this work? AFAIK, non-parameterized templates should
solve it. Or is it just a compiler issue?
FYI: This is a problem present in Phobos. You can use:
"equal!equal(RoR1, RoR2)"
To compare two ranges of ranges. equal!equal gets instanciated, because
the args are present to "finish" the missing R1/R2 args after pred.
However, this neat trick stop there:
"equal!(equal!equal)(RoRoR1, RoRoR2)"
This time, this does not work, as the compiler can't resolve the predicate.
I'd like to solve this. IMO "equal!equal" is one of the neatest "1-word"
in D, and I want to make sure it works as one would expect it to.
--------
So: Any workaround recommendations? Alternatives? Thoughts on
parameter-less templates (regardless of my issue)?