lua-users home
lua-l archive

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


2010/9/13 David Given <dg@cowlark.com>:
> On 13/09/10 14:43, steve donovan wrote:
> [...]
>> And also that a badly thought-out language feature is a backwards step
>> - try..catch is not as easy as it looks (as Duncan observes) and in
>> fact I found that it is not possible to do it with a token filter
>> precisely because an explicit 'return nil' has very different
>> semantics from simply ending the block.
>
> I managed to make this work for Objective Lua's @try...@catch. It was
> horrible. What it does is:
>
> - return inside a try/catch block returns the arguments;
> - exiting inside a try/catch block returns a special {} value;
> - we test what the pcall returns to see whether it's the special {}
> value, and if it is, it returns from the enclosing function.
>
> So it's really slow and clunky (but works).
>
> In addition, I've discovered that in an untyped language, exceptions are
> rather awkward to use, because you can't do this:
>
> @try
>  ...
> @catch (TypeOfException e)
>  ...
> @catch (AnotherTypeOfException e)
>  ...
> @end
>
> Instead you have to do runtime type checks:
>
> @try
>  ...
> @catch (e)
>  if e:IsTypeOfException() then
>    ...
>  elseif e:IsAnotherTypeOfException() then
>    ...
>  else
>    @throw e
>  end
> @end
>
> ...except it's even worse, because you need to check to make sure e
> really is an exception before you can call methods on it! (Because Lua
> doesn't have a formal exception system, code tends to throw strings or
> arbitrary tables instead of well-formed exception objects.) Javascript
> suffers from exactly the same problem, which is why they're not used
> much there. At least Javascript has instanceof, which helps.

Instead of Lua pcalls and errors, you could use coroutines and yields.
That way you can yield several values. You can then create a kind of
pattern matching syntax, with a mix of constants and variable names :

@try
 ...
@catch("TypeOfException", e)
 ...
@catch("AnotherTypeOfException", e)
 ...
@catch("YetAnotherTypeOfException", "subtype-foo", 42, e)
 ...
@end

Another benefit of coroutines is that you can resume them, and then
implement resumable exceptions.