lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Sep 18, 2014 2:23 PM, "Tim Hill" <drtimhill@gmail.com> wrote:

> This whole thing is a horribly gray area (witness pretty much every single computer language). To my mind the nearest you can get is distinguishing between “expected” and “unexpected” conditions in a program (which is, of course, itself horribly vague). For “expected” conditions, I prefer to use some kind of return value, while for unexpected conditions I use some kind of exception/throw mechanism.
>
> Example: FileOpen() fails because the file is not found. For me this is in the “return an error” bucket, since a program should always have code to cope with this, and that code should live close to where the file was opened.
>
> Example: Out of memory error. This is an exception, since pretty much all a program can even hope to do is cleanup as gracefully as possible and bail out.

I think you and William Ahern may have a fight scheduled over ENOMEM.

The resolution to the argument is probably to define how far out "bail out" goes. Probably not "while(1) { kill(getpid(), SIGKILL); }".

> It really comes down to “where is the code that handles this condition?”. If it’s close to the code that caused it, then the whole apparatus of exceptions or pcalls() is just an ornate way of returning an error code from the callee to the caller. If it’s far away, then you WANT an exception model so that you can avoid the absurd “ripple through” model where error codes have to be returned up a winding call stack.

Because there isn't a convention for describing what went wrong, there is very little to be done to recover from error() in programs composed of modules written by multiple authors. The meaning of error() in general Lua code ends up being "return to the REPL", or a suitable analog for web servers etc.

I am very assert-happy. In small programs this is OK, because the meaning for a raising an error can be: "I have no way I can recover from this, and neither do you."

Since many operations fail on nil, returning nil from a function where the value will be used can force the caller to either handle the exceptional or die. Consider:

  f = io.open("/tmp/a", "w")
  f:write(s)

Failure to open the file blows up on the attempt to retrieve nil["write"]. This achieves the goal of "prompt, local diagnosis". But if the value of f is simply stored for later use untouched, the failure of open may not be detected until very far away in time and/or source code.

It is not so obvious what to do when f:flush() fails, since people discard the return value.

Jay