Re: opDispatch, duck typing, and error messages

2011-04-24 Thread Jacob Carlborg

On 2011-04-24 01:39, Jonathan M Davis wrote:

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

Ok


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


Ok, I see that I was quite unclear. File and line info are available 
when an exception is thrown but not in the stack trace. If the stack 
trace uses the debug info then the problem is that the debug info 
segments are incorrectly named on Mac OS X.


--
/Jacob Carlborg


Re: opDispatch, duck typing, and error messages

2011-04-23 Thread 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.

--
/Jacob Carlborg


Re: opDispatch, duck typing, and error messages

2011-04-23 Thread 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.

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


Re: opDispatch, duck typing, and error messages

2011-04-22 Thread spir

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))



Who... 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



Re: opDispatch, duck typing, and error messages

2011-04-22 Thread spir

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



Re: opDispatch, duck typing, and error messages

2011-04-22 Thread spir

On 04/22/2011 03:53 AM, Robert Jacques wrote:

On Thu, 21 Apr 2011 18:24:55 -0400, Adam D. Ruppe destructiona...@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



opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
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))



Who... 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.

The fix:

// note the constraint
string opDispatch(string name)() if(name != popFront) {}


(I'm sure empty or front would have worked just as well, but popFront
I'm sure I didn't actually use anywhere for this.)


This post is to serve as two things: an FYI in case you see something
like this yourself, and to have a discussion on what we can do to
improve the situation.

A constraint like this wouldn't work of the Object was actually
supposed to be a range.


So, what can we do to improve that message? As it is now, it's
close to useless. Yeah, I was able to track down what it meant, but
only after I hacked up my copy of Phobos to tell me what T and S
actually were in the instantiation of to... then, it was obvious what
the error meant, but before, well, I pity the poor newbie who
stumbles upon that!


Things I think would help:

a) If the compiler gave some kind of stack trace in this instance. An
error message pointing solely at std.conv doesn't help much. In a
lot of template error messages, the kind of trace I want
already exists, so I suspect 90% of the work to implement it is
already done.

b) Format those constraints a little. Just put a \n\t before the
if and a \n before the function name. I think some whitespace
would help a lot in readability. Sure, newbs might still not get it,
but at least it won't be a blob of wtf.

Alas, I've looked at the compiler, but aren't to the point where I
can contribute code to it myself. Well, maybe I could do the
formatting change, but I haven't tried yet.

Regardless, let's look at other options.


c) Maybe Phobos could help out somehow? Another thing to!()
annoys the living crap of me with is it's runtime errors. It, again,
doesn't tell me where in my code the problem occurred.

Perhaps have it take default __FILE__ and __LINE__ args to print out
too? I think this can help both compile and runtime errors.

d) Also in Phobos, I wonder if we can beautify the message somehow.
I don't have any idea how to do this in a scalable way.

It could static if (matches constraint 1 and constraint 2)
static assert(pretty message), but there's no chance that would
scale well.

So I don't know here.


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.



I kinda blabbered here, but in the end, I think my previous paragraph
is the big thing. It's a fairly minor Phobos change. Any objections
to it?

Note btw that I'd still like the error messages to be prettier, but
I'm ok doing it one step at a time.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread bearophile
Adam D. Ruppe:

 c) Maybe Phobos could help out somehow? Another thing to!()
 annoys the living crap of me with is it's runtime errors. It, again,
 doesn't tell me where in my code the problem occurred.
 
 Perhaps have it take default __FILE__ and __LINE__ args to print out
 too? I think this can help both compile and runtime errors.

This is a more general problem of runtime errors, not just of to!(). 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).

Bye,
bearophile


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
 Adam D. Ruppe:
  c) Maybe Phobos could help out somehow? Another thing to!()
  annoys the living crap of me with is it's runtime errors. It, again,
  doesn't tell me where in my code the problem occurred.
  
  Perhaps have it take default __FILE__ and __LINE__ args to print out
  too? I think this can help both compile and runtime errors.
 
 This is a more general problem of runtime errors, not just of to!(). 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).

Most exceptions end up with file and line numbers. The problem is generally 
not that they don't have a file or line number, it's that the file and line 
number is from inside of a function that you called instead of your own code. 
As long as you have a stack trace, it's not all that big a problem, but if 
you're on Windows, then there are no stack traces yet and you're screwed. 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.

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. One example of that is 
converting a string to anything else. The value of the string determines 
whether the conversion is valid rather than the types being enough at compile 
time. So, in some cases, you _have_ to have an exception at runtime rather 
than a compile time error. Whether to does as good a job with making errors 
compile time errors as much as it can, I don't know, but on some level, we're 
stuck.

But generally, I think that the real problem is the lack of a stack trace. You 
generally get them on Linux but not Windows. Most exceptions _should_ be 
grabbing the file and line number that they're thrown from. I don't recall of 
Exception can or not (Error _can't_ due to some low level stuff), but pretty 
much everything derived from Exception certainly can and should.

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
 This is a more general problem of runtime errors, not just of to!(). 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).

Vote up for that. At least it should do that in -debug mode. It's
completely useless getting an error message with a file and line
number for an internal Phobos function, like some funcImpl() private
function, when the fault is a runtime argument.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
Btw, there is a stack trace for Windows and D2, see here:
http://3d.benjamin-thaut.de/?p=15


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
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?


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
 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?

I just checked. Exception _does_ take a default file and line number. So, 
anything derived from Exception doesn't have a file and line number, something 
is amiss.

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Sean Kelly
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.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread 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!

 One example of that is converting a string to anything else. The
 value of the string determines whether the conversion is valid
 rather than the types being enough at compile time.

The runtime error is actually pretty good. If it had a nice
stack trace with line numbers I'd call it outright excellent.


So I agree with your conclusion too about the stack trace!


BTW, while I'm talking about this, is RangeError at all possible
to include the actual key that was out of range?

int[] b;
int c = b[3];
core.exception.RangeError@test60(7): Range violation

Good, but I'd call it great if it could say Range violation (3) or
something like that.

I imagine since it's an Error there might be memory allocation
restrictions... but if it's possible, that'd be way cool too.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread 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.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
 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


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
 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


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
On 4/22/11, Sean Kelly s...@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.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
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


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Robert Jacques
On Thu, 21 Apr 2011 18:24:55 -0400, Adam D. Ruppe  
destructiona...@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.