digitalmars.D - better error messages on isInputRange, etc.
- Adam D. Ruppe (46/46) Feb 26 2014 When isInputRange fails, it doesn't tell us why. Did you not add
- H. S. Teoh (23/32) Feb 26 2014 We've talked about this before. I proposed the idea that sig constraints
When isInputRange fails, it doesn't tell us why. Did you not add empty? Or misspell popFront? It just tells you it isn't a range. I'm thinking a better way might be to write the check like this: // compile a regular function so we get full error from the compiler... bool checkInputRange(T)() { if(!__ctfe) { // don't want to *actually* run it T t = void; if(t.empty) {} t.popFront(); auto f = t.front; } return true; } // and isInputRange is basically the same as today, but the // helper function isn't anonymous template isInputRange(T) { enum isInputRange = is(typeof(checkInputRange!T)); } Consider this: struct Test { int[] s; bool eampty() { return s.length == 0; } int front() { return s[0]; } void popFront() { s = s[1 .. $]; } } static assert(isInputRange!Test); cte.d(33): Error: static assert (isInputRange!(Test)) is false We know it failed, but we don't know why. Change the assert to this: static assert(checkInputRange!Test); And we get a more helpful error: cte.d(4): Error: no property 'empty' for type 'Test', did you mean 'eampty'? Still not perfect, it points to the helper function line, but at least the "no property 'empty' for type 'Test'" is a lot more specific. Fix the typo and it all works. Any better ideas? I just sometimes get frustrated, especially with more complex ranges, when the duck type doesn't work and it is hard to find why. This is one idea. On a similar vein, template constraints can lead to some ugly messages. Why didn't it match any of them? But I think this has to be a compiler change and might spam all kinds of nonsense, whereas tweaking isInputRange etc. is a fairly conservative change that I think will help a lot too.
Feb 26 2014
On Thu, Feb 27, 2014 at 04:12:02AM +0000, Adam D. Ruppe wrote: [...]Any better ideas? I just sometimes get frustrated, especially with more complex ranges, when the duck type doesn't work and it is hard to find why. This is one idea. On a similar vein, template constraints can lead to some ugly messages. Why didn't it match any of them? But I think this has to be a compiler change and might spam all kinds of nonsense, whereas tweaking isInputRange etc. is a fairly conservative change that I think will help a lot too.We've talked about this before. I proposed the idea that sig constraints should be used to pick up *all* "logical" types that you want to support, and static ifs used to narrow down which subset of the accepted logical types is actually implemented for. Example: auto sort(R)(R range) if (isInputRange!R) // N.B. we accept *any* range: // "sort a range" is the logical // category we cover for. { // N.B. our implementation can only handle random access // ranges, so use static if. static if (!isRandomAccessRange!R) static assert(0, "Don't know how to sort a non-random access range"); else { // implementation here } } But it's not perfect, though. T -- Real men don't take backups. They put their source on a public FTP-server and let the world mirror it. -- Linus Torvalds
Feb 26 2014