lua-users home
lua-l archive

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


On Jul 20, 2012, at 2:09 AM, steve donovan wrote:

> On Fri, Jul 20, 2012 at 12:16 AM, Pierre-Yves Gérardy <pygy79@gmail.com> wrote:
>> That being said, it would also hide bugs that would be catched with
>> the current way of doing things...
> 
> Oh and they can be nasty - think about io.lines - if there was no
> distinction between io.lines() and io.lines(nil) then a script could
> easily jam due to a silly error.  It's better to fail with a big fuss
> than just hang!

Speaking of which, Perl has this nice module autodie ( http://search.cpan.org/perldoc?autodie ) which might be fun to think about in Lua.

> The autodie pragma provides a convenient way to replace functions that normally return false on failure with equivalents that throw an exception on failure.
> 
> The autodie pragma has _lexical scope_, meaning that functions and subroutines altered with autodie will only change their behaviour until the end of the enclosing block, file, or eval.

If you have made it to the point where you write "local A=assert" at the top of your code, something like this sounds fun. Codifying better exception handling is probably then a priority.

And while we're on the subject of exception handling, I have come to really like Python's "with" statement:

    with open(filename) as f:
        f.do_stuff()
        sys.something_which_can_blow_up()

where f.__enter__() is called on the way in, and f.__exit__() is called on the way out--regardless of whether the "with" statement falls off the end, exits with return/break, or via exception. With coroutines, control flow can wander off and never come back; I guess you'd call f.__exit__() when the thread was gc'd.

The syntax of a Lua translation would be:

  with(open(filename), 
    function (f) f.do_stuff() end
  )

which doesn't have to handle the "break" case of course. The xpcall is a little expensive, but there is no alternative. Like try/except/finally, this is another case where we do not need a full closure; Smalltalk-like blocks are sufficient. Their lifetime can be bound by the function call they're associated with, although I'm not sure what it would take to make them escape-free. 

Oh yeah, the same is true of a better log; if the log level is turned off, you want to skip the message evaluation:

  log(DEBUG, function() return "complicated expensive expression "..o:full_state() end)

This pattern of stack-allocatable closures keeps showing up--just about everywhere I said I wanted terse lambdas, I really only wanted this. Now I wonder how to booby-trap them so map() won't work...maybe keep "return" as the return of the lexically enclosing function....

Jay