lua-users home
lua-l archive

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



On 11-Aug-05, at 12:35 PM, Diego Nehab wrote:

Hi,

This could be resolved with a non-local return mechanism for Lua that would
let one build a function to do the following:

   local image, quality = return_if_nil( get_image_and_quality() )

I like this idea. I actually thought about it but it didn't seem to be
possible without modifying Lua somehow. That's why I use exceptions. We
could have two versions of this function, the return_if_nil would be for
soft errors. Another version would throw an exception.

I like this, too, with a slight generalization.

This syntax is roughly borrowed from Dylan:

<exp> --> ... | <blockexp>
<blockexp> -->  block <Name> <block> end

The semantics are that block binds <Name> to a function which when called will cause the block to return as value(s) the arguments to the function. To simplify implementation, the non-local-exit function is only valid during the dynamic execution of the <blockexp>

The invalidation of the non-local-exit object could be reliably accomplished by using two stack slots, one of which is hidden. The hidden slot would then be unmodifiable by the enclosed code, and a hook in the luaF_close() mechanism could be used to mark the associated nle object as invalid.

A slightly more sophisticated implementation would allow 'finally' (non-optional exit) clauses in the block; again, the link to the finally clause would be stored in a hidden stack slot and triggered by luaF_close(), which would guarantee that it was called by error().

Now:

function call_if_false(nle, arg1, ...)
  if arg1 then return arg1, ...
          else nle(nil, (...)) -- assume the second arg is an error
  end
end

function foo()
  return
    block nle
      local image, quality = call_if_false(nle, get_image_and_quality())
      local x, y = call_if_false(nle, get_dimensions(image))
      -- ...
      return true
    end
end


The main problem with the implementation is that the Lua code generator does not allow locals to be defined in an expression; the modification to allow this is not enormous, nor does it add much bulk. (I had to do it in order to implement table comprehensions.)