April 21, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | > Jonathan M Davis wrote:
> > It _does_ generally make sense for the file and line number to be from the throw point rather than the point where you called the function (especially when the throw point could be several function calls away in the stack), but without a proper stack trace, you have no way of knowing where in your code the problem is.
>
> I believe I agree completely.
>
> > Now, in the case of something like to, the types are known at compile time, so in many cases, it should be able to give a compile time error via a template constraint, but it's not able to do that in all cases.
>
> Indeed. And it usually does. The problem is that the error can be pretty hard to read.
>
> Here's one simple case:
>
> ===
>
> import std.conv;
>
> struct Test {}
>
> void main() {
> Test t;
> int a = to!int(t);
> }
>
> ===
>
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) does not match
> any function template declaration
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) cannot deduce
> template function from argument types !(int)(Test)
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> instance errors instantiating template
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(7): Error: template
> instance std.conv.to!(int).to!(Test) error instantiating
>
>
> Holy crap!
>
> But, if you know the secret there - to look at the last line - it does tell you enough to do some useful stuff. Alas, it doesn't tell where in *your* code the problem is, but it does tell the types you asked for, so it's pretty useful.
>
> Still, I'd like it if that was formatted nicer, and it went the final step of telling me where in my code the problem is too.
>
>
> Then, you have the problem if your type matches two templates. Then you have the vomit in my opening post, where it doesn't even tell you what types it's having trouble with!
Template errors tend to be fairly good (especially if you're used to reading them) when you're only dealing with one template, but as soon as the template is overloaded, you're screwed. It generally just gives the first template and says that you didn't match it, and often the template that you're actually trying to use is quite different. But short of giving _all_ of the possible template declarations that it failed, I'm not quite sure what we could do to fix that.
- Jonathan M Davis
| |||
April 21, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | > Jonathan M Davis wrote:
> > I just checked. Exception _does_ take a default file and line number.
>
> Huh, maybe my dmd is getting old.
>
> Maybe we should revisit this after the next dmd release. Sounds like one is coming pretty soon with a lot of yummy goodness in it. All of this Exception stuff may be moot.
It was in dmd 2.052. I don't know when the change was made though. I might have been the one to change it too. I made several changes a while back to make it so that Exception and Error types had default file and line numbers (and I actually had to remove several on various Errors, because the way that they're actually created makes them not work with default arguments).
- Jonathan M Davis
| |||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
On 4/22/11, Sean Kelly <sean@invisibleduck.org> wrote:
> On Apr 21, 2011, at 4:10 PM, Andrej Mitrovic wrote:
>
>> Btw, there is a stack trace for Windows and D2, see here: http://3d.benjamin-thaut.de/?p=15
>
> Already in the next DMD release.
>
Whoa, the next release is gonna be big.
| ||||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis wrote:
> It was in dmd 2.052.
This is almost definitely my error then... I still have 2.050!
I didn't realize so much has passed since my last update :S
| |||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Thu, 21 Apr 2011 18:24:55 -0400, Adam D. Ruppe <destructionator@gmail.com> wrote: [snip] > Or, there's a whole new approach: > > e) Duck typing for ranges in to!() might be a bad idea. Again, remember, > a class might legitimately offer a range interface, so it would > trigger this message without opDispatch. > > If ranges are meant to be structs, maybe isInputRange should check > is(T == struct)? This doesn't sit right with me though. The real > problem is to!() - other range functions probably don't overload > on classes separately than ranges, so it won't matter there. > > > I think the best thing to do is simply to prefer Object over range. > > toImpl(T) if (isInputRange!(T) && (!is(T : Object))) > > Or something along those lines. Why? If the object has it's own > toString/writeTo methods, it seems fairly obvious to me anyway that > to!string ought to simply call them, regardless or what else there is. There's actually a bug report regarding the toString vs range semantics issue, it's issue 5354 ( http://d.puremagic.com/issues/show_bug.cgi?id=5354 ). Also note that classes (but not structs as of yet, see bug 5719) can provide their own to!T conversions. However, what you ran into deserves a new bug report, since to!string should always be able to fall back to toString and it didn't. | |||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 04/22/2011 12:24 AM, Adam D. Ruppe wrote: > I just made an innocent little change to one of my programs, hit > compile, and got this vomit: > > /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(97): Error: template > std.conv.toImpl(T,S) if (!implicitlyConverts!(S, > T)&& isSomeString!(T)&& isInputRange!(Unqual!(S))&& > isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S > ,T)&& isSomeString!(T)&& isInputRange!(Unqual!(S))&& > isSomeChar!(ElementType!(S))) matches more than one template declar > ation, /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(185):toImpl(T,S) > if (isSomeString!(T)&& !isSomeChar!(ElementT > ype!(S))&& (isInputRange!(S) || isInputRange!(Unqual!(S)))) and > /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(289) > :toImpl(T,S) if (is(S : Object)&& isSomeString!(T)) > > > > Whooooo... took a bit to figure out what it was saying. The bottom > line: one of my classes matched both Object and isInputRange because > it offers an unrestricted opDispatch. > >[...] > > Things I think would help: > > [...] > > Or, there's a whole new approach: > > e) Duck typing for ranges in to!() might be a bad idea. Again, remember, > a class might legitimately offer a range interface, so it would > trigger this message without opDispatch. Maybe we could replace template constraints, esp. 'is' stuff, by (structural) interfaces. The difference in my views is structural interface is a compile-time / static feature, while duck typing is runtime/dynamic. > If ranges are meant to be structs, maybe isInputRange should check > is(T == struct)? This doesn't sit right with me though. The real > problem is to!() - other range functions probably don't overload > on classes separately than ranges, so it won't matter there. > > > I think the best thing to do is simply to prefer Object over range. > > toImpl(T) if (isInputRange!(T)&& (!is(T : Object))) > > Or something along those lines. Why? If the object has it's own > toString/writeTo methods, it seems fairly obvious to me anyway that > to!string ought to simply call them, regardless or what else there is. Sure. I hit and discussed a similar issue (maybe the same one in fact). The problem was with template formatValue which constraints: (1) for structs, ignore programmer-defined toString in favor of standard format for ranges (2) for classes, simply fail because of conflict (double match) There's a bug report (search for 'formatValue'). Denis -- _________________ vita es estrany spir.wikidot.com | |||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On 04/22/2011 01:25 AM, Adam D. Ruppe wrote: > bearophile wrote: >> Maybe exceptions nature should be changed a little so they store >> __FILE__ and __LINE__ on default (exceptions without this >> information are kept on request, for optimization purposes). > > I'd like that. Even with a stack trace, it's nice to have that > available right at the top. > > A while ago, someone posted a stack tracer printer for Linux to > the newsgroup. Using that, this program: > > void main() { > throw new Exception("test"); > } > > dmd test60 -debug -g backtrace.d > > Prints: > > object.Exception: test > ---------------- > ./test60(_Dmain+0x30) [0x807a5e8] > ./test60(extern (C) int rt.dmain2.main(int, char**) . void runMain()+0x1a) [0x807d566] > ./test60(extern (C) int rt.dmain2.main(int, char**) . void tryExec(void > delegate())+0x24) [0x807d4c0] > ./test60(extern (C) int rt.dmain2.main(int, char**) . void runAll()+0x32) [0x807d5aa] > ./test60(extern (C) int rt.dmain2.main(int, char**) . void tryExec(void > delegate())+0x24) [0x807d4c0] > ./test60(main+0x96) [0x807d466] > /lib/libc.so.6(__libc_start_main+0xe6) [0xf75a5b86] > ./test60() [0x807a4e1] > > > > No line or file info! I'd really like to have something there. > Though, actually, whether it's in the message or in the stack > trace doesn't really matter. As long as it's there somewhere. > > Most my custom exceptions use default params in their constructor > to add it. Perhaps the base Exception should too? Also, addresses could go (useless). Denis -- _________________ vita es estrany spir.wikidot.com | |||
April 22, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Jacques | On 04/22/2011 03:53 AM, Robert Jacques wrote: > On Thu, 21 Apr 2011 18:24:55 -0400, Adam D. Ruppe <destructionator@gmail.com> > wrote: > [snip] >> Or, there's a whole new approach: >> >> e) Duck typing for ranges in to!() might be a bad idea. Again, remember, >> a class might legitimately offer a range interface, so it would >> trigger this message without opDispatch. >> >> If ranges are meant to be structs, maybe isInputRange should check >> is(T == struct)? This doesn't sit right with me though. The real >> problem is to!() - other range functions probably don't overload >> on classes separately than ranges, so it won't matter there. >> >> >> I think the best thing to do is simply to prefer Object over range. >> >> toImpl(T) if (isInputRange!(T) && (!is(T : Object))) >> >> Or something along those lines. Why? If the object has it's own >> toString/writeTo methods, it seems fairly obvious to me anyway that >> to!string ought to simply call them, regardless or what else there is. > > There's actually a bug report regarding the toString vs range semantics issue, > it's issue 5354 ( http://d.puremagic.com/issues/show_bug.cgi?id=5354 ). Also > note that classes (but not structs as of yet, see bug 5719) can provide their > own to!T conversions. > > However, what you ran into deserves a new bug report, since to!string should > always be able to fall back to toString and it didn't. > Agreed. A programmer who defines toString *means* it to be used for conversion to string (esp. for write* funcs). Please support and vote for this bug ;-) Denis -- _________________ vita es estrany spir.wikidot.com | |||
April 23, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2011-04-22 01:54, Jonathan M Davis wrote: >> Jonathan M Davis wrote: >>> I just checked. Exception _does_ take a default file and line number. >> >> Huh, maybe my dmd is getting old. >> >> Maybe we should revisit this after the next dmd release. Sounds like >> one is coming pretty soon with a lot of yummy goodness in it. All >> of this Exception stuff may be moot. > > It was in dmd 2.052. I don't know when the change was made though. I might > have been the one to change it too. I made several changes a while back to > make it so that Exception and Error types had default file and line numbers > (and I actually had to remove several on various Errors, because the way that > they're actually created makes them not work with default arguments). > > - Jonathan M Davis It would nice to have file and line info available on Mac OS X as well. -- /Jacob Carlborg | |||
April 23, 2011 Re: opDispatch, duck typing, and error messages | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | > On 2011-04-22 01:54, Jonathan M Davis wrote:
> >> Jonathan M Davis wrote:
> >>> I just checked. Exception _does_ take a default file and line number.
> >>
> >> Huh, maybe my dmd is getting old.
> >>
> >> Maybe we should revisit this after the next dmd release. Sounds like one is coming pretty soon with a lot of yummy goodness in it. All of this Exception stuff may be moot.
> >
> > It was in dmd 2.052. I don't know when the change was made though. I might have been the one to change it too. I made several changes a while back to make it so that Exception and Error types had default file and line numbers (and I actually had to remove several on various Errors, because the way that they're actually created makes them not work with default arguments).
> >
> > - Jonathan M Davis
>
> It would nice to have file and line info available on Mac OS X as well.
Whether there is file and line info with an exception should have nothing to do with the OS, except perhaps in some low-level stuff that druntime does, but I don't think that it makes a difference even then. Pretty much anything and everything derived from Exception should give a file and line number - generally that file and line number are the point where the exception was thrown from. Many Errors _can't_ have proper file and line numbers due to how they're thrown, though some of them (such as AssertError) should have proper file and line numbers.
So, I don't know why you wouldn't be seeing file and line numbers on Mac OS X. It should be the same as the other OSes. Stack traces are another issue (and I have no idea if Mac OS X currenly has them), but the behavior with regards to file and line numbers in exceptions should be the same for all OSes. I don't know why they wouldn't be.
- Jonathan M Davis
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply