digitalmars.D.learn - Doubt about type Inference on templates
- Antonio (49/49) Nov 22 2023 Just for fun, I'm trying to implement an alternative base library
- Paul Backus (20/29) Nov 22 2023 This is a bug/limitation in the compiler. I couldn't find an
- Antonio (5/23) Nov 23 2023 Wow: It is a very concise bug example.
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.: ```d 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 ```d 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?**
Nov 22 2023
On Wednesday, 22 November 2023 at 17:53:15 UTC, Antonio wrote: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?**This is a bug/limitation in the compiler. I couldn't find an existing report on issues.dlang.org, so I've reported it myself as [issue 24255][1]. For now, I think the best way to work around it is to specify the type in the lambda, as in `(int i) => i%2 == 0`. The reason you see `void` is that when the compiler cannot figure out the type of a function literal, it treats it as a template function: ```d static assert(__traits(isTemplate, i => i % 2 == 0)); ``` And for silly historical reasons, when the compiler tries to determine the type of a template, it returns `void` instead of giving an error: ```d template example() {} static assert(is(typeof(example) == void)); // what?? ``` [1]: https://issues.dlang.org/show_bug.cgi?id=24255
Nov 22 2023
On Wednesday, 22 November 2023 at 19:37:58 UTC, Paul Backus wrote:This is a bug/limitation in the compiler. I couldn't find an existing report on issues.dlang.org, so I've reported it myself as [issue 24255][1].Wow: It is a very concise bug example. I tested with ```ldc``` ant it fails too.For now, I think the best way to work around it is to specify the type in the lambda, as in `(int i) => i%2 == 0`.agreedThe reason you see `void` is that when the compiler cannot figure out the type of a function literal, it treats it as a template function: ```d static assert(__traits(isTemplate, i => i % 2 == 0)); ``` And for silly historical reasons, when the compiler tries to determine the type of a template, it returns `void` instead of giving an error: ```d template example() {} static assert(is(typeof(example) == void)); // what?? ```Thanks Paul!!!
Nov 23 2023