On Tue, Jan 09, 2007 at 09:33:52AM -0800, Larry Wall wrote: > The Perl 6 perspective on this is that error values should be allowed to > be as "interesting" as you like. The lower level routine goes ahead and > pregenerates the exception object but returns it as an interesting > error value instead of throwing it. Then the calling code can just > decide to throw the unthrown exception, or it can generate its own > exception (that perhaps includes the unthrown exception). In any case, > you get a better error message if you include all the relevant facts > from the lower-level routine, and those tend to get lost with scalar > error values. By returning an object you still a simple test to see > whether there's an exception, but you're not limiting the information > flow by assuming all the information passes through whatever scalar > is functioning as the boolean value of "oops". > > In any case, this would certainly make it easier to put Perl 6 on top. :)
It would actually also make it easier to put Perl 5 done-with-hindsight on top of :-) One of the issues with writing IO layers in Perl 5 is that the existing interface is defined in terms of Perl builtins that return undef on failure, and set C<$!>, and in turn C<$!> is only allowed to hold a small vocabulary of integer codes (typically around 100) which are defined by the operating system, for use in reporting operating system level errors. This works well on regular IO, talking direct to the operating system, but goes pear shaped when you write an IO layer, and want to report an error condition. You're forced to make a lossy mapping of your true error condition (such as detecting an invalid character encoding or corrupt compressed data) into the least inappropriate errno value. It would be much nicer to have the option of returning true objects. On Wed, Jan 10, 2007 at 09:26:22AM -0800, Larry Wall wrote: > Possible optimization: for those success values that are sufficiently > "uninteresting" maybe they could just be refs to constant shared > objects so you avoid allocating them every time. Even if you have to > return some integer like a number of characters read, this is usually > the same number till the last block of the file, so that could be > factored out. If most IO operations are actually returning the OS error code, then having around 128 cached shared objects for boxing up each errno value seems feasible to me. > Or it could be an out-of-band thing like errno, but it would just > happen to be an out-of-band object instead of an integer. I can imagine > various states in between where it looks out-of-band but really comes > through the return interface for cleanness. Out of band things feel bad. I'm not sure how parrot will implement concurrency, but C's return -1 with out-of-band errno feels like a mistake to avoid. It ends up with C implementations having to use icky hacks to make something that feels like it's extern int errno; but is actually thread local (whilst still being read/write). The Linux Kernel made a nicer decision to change from -1 to a negative value (just as efficient to check) where the negative value happens to be the errno value. The POSIX threads API avoids conflating value returns with error returns by specifying that the return value is success-or-positive-errno, but again it's avoiding anything out of band, or seemingly-out-of-band. Nicholas Clark