Handling Errors (continued)

Alastair Reid alastair at reid-consulting-uk.ltd.uk
Sat Apr 26 09:15:13 EDT 2003

Gustavo Villavicencio <gustavov at ucse.edu.ar> writes:
> [...]
> 1- getMem s = catch (do m <- newCString s
>                         return m)
>                     (\_ -> return nullPtr)
>               -- the exception handler could be more elaborated.
> [...]
> Which of the three solutions, including those of Alastair, would be
> better?

I would strongly encourage you to maintain the invariant that values
of type 'Ptr a' are never null (at least, in any code and libraries
you write) and to either:

1) use the type 'Maybe (Ptr a)' for pointers that could be null
2) throw exceptions where appropriate.

The benefit from using Maybe is that the typesystem will catch a bunch
of errors that would otherwise have lead to uncaught errors,
segmentation faults, etc.  Also, when you look at a type like:

    Ptr X -> Maybe (Ptr Y) -> IO ()

you will naturally ask yourself 'what happens if the 2nd argument is null?'.
Whereas the type

    Ptr X -> Ptr Y -> IO ()

either doesn't make you ask the question or also has you wondering
'what happens if the 1st argument is null?'

I used this approach extensively in the Win32 library and found it
caught a lot of potential errors.  (It also exposed just how bad the
documentation for C functions is - many functions didn't document what
using a null pointer would do even when it was valid to use one.)

Throwing exceptions when a null pointer is returned can be another
good way of dealing with keeping null pointers.  It catches much the same
issues that the 'Maybe (Ptr a)' approach catches but:

1) It catches them closer to where the error occured which is easier to
   reason about, write exception handlers for and debug.

2) The exception propagation mechanisms make it a bit harder to
   pinpoint precisely where an error occured.  (Not impossible, not
   even hard but a bit harder.)

3) What is an exception/error and what is a non-error is a difficult
   decision.  In many cases, you could find programs that are simpler
   for using exceptions and programs that would be simpler if 
   explicit error values (e.g., Maybe Char, Either Error Int, ...)
   were used.

Alastair Reid                 alastair at reid-consulting-uk.ltd.uk  
Reid Consulting (UK) Limited  http://www.reid-consulting-uk.ltd.uk/alastair/

More information about the FFI mailing list