I'm a big fan of Lua's use of nil and the simplified error handling (No exception 'types') in that language. I think the problem with 'typing' Exceptions is that it means you are using it to record and pass describable\known state similar to return, instead of being reserved for unknown state. For indicating predictable failure states without using exceptions, I think multiple return values is a much better paradigm. Here's what happens when you open a non-existent file in Lua:
=io.open 'sdfasdf'
nil sdfasdf: No such file or directory 2
The first value returned is nil, the 2nd value is a string containing an error message, and the 3rd is an integer error code. This allows you to write most code using 2 state boolean logic:
f=io.open 'sasdasdfsf'
if f then -- nil is a boolean 0
whereas in Python, one often has to reason about 3 states by using the try\except blocks. Even though you are not using typed Exceptions, multiple return values does not discard any state about the error if it is desired:
This also works really well when combined with the assert function. Any function that returns nil and an error on failure can be wrapped in assert (which is just a normal function that takes a value and a message, and raises an error with the message if the value is nil or false).
If the function returned a value (besides nil or false), then assert merely returns the value. If the function returns nil or false, then assert raises an error, and the error message is used as the error in the assert. For example:
> = assert(io.open("hello"))
file (0x8b9f658)
> = assert(io.open("goodbye"))
stdin:1: goodbye: No such file or directory
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: ?
This makes it possible to fail early when you don't need or want to do full error handling, or to use advanced logic if you need to recover from the error - without a try/catch statement. Effectively, it makes exceptions optional.
Comments
I'm a big fan of Lua's use of nil and the simplified error handling (No exception 'types') in that language. I think the problem with 'typing' Exceptions is that it means you are using it to record and pass describable\known state similar to return, instead of being reserved for unknown state. For indicating predictable failure states without using exceptions, I think multiple return values is a much better paradigm. Here's what happens when you open a non-existent file in Lua:
The first value returned is nil, the 2nd value is a string containing an error message, and the 3rd is an integer error code. This allows you to write most code using 2 state boolean logic: whereas in Python, one often has to reason about 3 states by using the try\except blocks. Even though you are not using typed Exceptions, multiple return values does not discard any state about the error if it is desired: I believe this also the design decision Google's Go language has made: http://golang.org/doc/effective_go.html#multiple-returnsThis also works really well when combined with the assert function. Any function that returns nil and an error on failure can be wrapped in assert (which is just a normal function that takes a value and a message, and raises an error with the message if the value is nil or false).
If the function returned a value (besides nil or false), then assert merely returns the value. If the function returns nil or false, then assert raises an error, and the error message is used as the error in the assert. For example:
This makes it possible to fail early when you don't need or want to do full error handling, or to use advanced logic if you need to recover from the error - without a try/catch statement. Effectively, it makes exceptions optional.