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