There are too many error handling conventions used in library code!

Jack Waugh 95h62gq02 at sneakemail.com
Fri Aug 12 21:35:06 CEST 2011


In re
http://thread.gmane.org/gmane.comp.lang.haskell.libraries/6382

I read this thread (as I found it populated on 2011-08-12)
with interest even though I have not written three lines
of Haskell.

I am trying to invent a programming language with
referential transparency and I am thinking about what
construct(s) it should provide to catch errors.  Catching
errors is necessary because I want the language to be
suitable for building systems that run code by various
contributors without trusting the integrity of the system
as a whole to the contributions.  Errors should be caught
and reported to the responsible programmers.

Let "RT" stand for referential transparency or
referentially transparent as grammatically appropriate in
each instance.

I wanted to learn from the experience with Haskell because
Haskell is one of the few pure functional programming
languages in use (I'm not sure about the ML family, and I'm
pretty sure that Erlang and the E language are not pure).
At least with Haskell I know for sure it is pure, so
I think that the community around Haskell has advanced
understanding of how to go far within a purely RT world.

So I start poking around to figure out how errors are
caught, and the upshot, from this thread, seems to be,
that errors cannot be caught in Haskell.  I see you all
talking about how libraries' APIs should incorporate
error reporting, but these seem like really exceptions
rather than errors, in that you, the library prorammers,
have to plan to detect them and you are just looking
for a non-noisy way to pass them back through the API,
since these "errors" represent cases that for good reason
shouldn't dominate the body of your code (all of us would
prefer, and with excellent reason, that the bulk of our
code reflects programming for the normal and happy cases).
Maybe these error cases you're discussing, some of them,
reflect an error on the part of the programmer of the
_client_ code _calling_ the library, and that's why you
want to use the term "error".  But a true programming error
(for example, in the library code) might not be possible
to anticipate and program around; after all, it's an error.
A programming mistake.

For example, what happens if we try to take the head of
an empty list?  Everything dies, right?  Haskell won't
catch that, right?

So, here's what I'm thinking for my language.  Every data
type (I don't think I'll need Unit) will have implicitly
some error indications as possible values.
 So for example, if an Integer is expected, we might get
 an integer, such as 3
for example, but we could instead receive an error
indication.  It should be possible to test explicitly
for an error indication, and on finding one, it should be
possible to test it for membership in various interesting
classes of errors (including programmer-defined ones) and
it should be possible to dig into the error indication and
extract a brief explanation in natural language of what
went wrong.  I'm thinking location information such as
source file name (or something like that) and line number
could fit in there as well.

Functions that are not designed for the explicit purpose of
looking for error cases, for example `+`, would propagate
errors along to their results if such were found in one or
more essential inputs (False && error could return False
rather than the error).

Now if it looks as though I'm just reinventing
something that a monad can do elegantly, I'm not sure.
The monadic examples I have been seeing all seem to
require the use of the bind function to glue together
the function applications that could encounter an error.
A reader of the code can't tell that the order of the
binds doesn't matter.  It looks like I/O code, where the
order definitely does matter.  But if I want to return for
example a/b + c/d, and either division could accidentally
attempt to divide by zero, I don't want to specify which
division comes "first" in some chain of binds; that's
overspecification, isn't it?  Because the result does
not depend on any ordering of the addends.  Addition is
commutative, and it remains commutative if we extend the
domains to include error indications.  Error some_specs
+ 3 = Error some_specs; 3 + Error some_specs = Error
some_specs; still commutative.

If I adopt this scheme, have I learned everything I can
about error catching from Haskell and incorporated that
learning into my design?

I apologize for posting off topic in your thread, but
this is a branching topic closely related to your topic
and if I can get the advice of people who are experienced
in pure functional programming and who have thought about
the problems of error reporting, I might be able to avoid
making some really stupid design mistake.

I suggest the subject "Learning from Haskell -- Catching
Errors" as the subject for any followups to this message.

Thanks loads for any response.  And if you think my idea
is crackpot, please don't hold back on your opinion.
I am trying to make a useful contribution, and if I am
barking up the wrong tree, that purpose will not be served.
Please feel free to tell me I should read one thing or
another that my question indicates I have missed, before
trying to design a new RT programming language.

Again, my question is "If I adopt this scheme, have I
learned everything I can about error catching from Haskell
and incorporated that learning into my design?"

Jack Waugh http://jackwaugh.com/





More information about the Libraries mailing list