Just for fun, I'm trying to implement an alternative base library to avoid template/mixin/static/traits code with only one objective: make "intelliSense" code analyzers tasks easier.
I need "Generics"... but D has not generics: I use templates in the "simplest" possible way
I.E.:
interface IIterable(T)
{
bool empty();
void popFront();
T front();
}
IIterable!S toIterable(S)(S[] source)
=> new ArrayIterable!S(source);
IIterable!S filter(S)(IIterable!S source, bool delegate(S item) predicate)
=> new Filter!S(source, predicate);
IIterable!S filter(S)(S[] source, bool delegate(S item) predicate)
=> toIterable(source).filter(predicate);
// ...
Then, in main.d I do
import std.stdio;
void main(){
[1,2,3,4,5,6].toIterable!int.filter!int(i=>i%2==0).map!int(i=>i*2).toArray.writeln();
}
It works properly... until I remove the !int
from the filter
method.
main.d(3,38): Error: none of the overloads of template `filter` are callable using argument types `!()(IIterable!int, void)`
iterable.d(21,13): Candidates are: `filter(S)(IIterable!S source, bool delegate(S item) predicate)`
iterable.d(23,13): `filter(S)(S[] source, bool delegate(S item) predicate)`
Basically, it doesn't know witch version of filter
to use, because it is inferring i=>i%2==0
is void
?!?!?!
!()(IIterable!int, void)
If I explicitly write (int i)=>i%2==0
, it compiles correctly again.
Is it mandatory to explicitly tell that S
is int
when IIterable!S source
is IIterable!int
alredy?