[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Non Local Exits: Draft Implementation
- From: Rici Lake <lua@...>
- Date: Fri, 12 Aug 2005 14:24:34 -0500
On 12-Aug-05, at 2:05 PM, Diego Nehab wrote:
Hi Rici,
Don't you think it can get quite complicated to trace where these
blocks reside once you start passing them around?
No, I don't.
I didn't mean it would be hard to implement. I meant it might make the
Lua code that uses this functionality very hard to understand. This
could be a limitation of my not being used to non-local returns. I
remember once not liking coroutines. :)
But I do think we have found a valid use for this non-local return:
error checking.
Wouldn't a simplistic solution be enough, though? How about a construct
that behaves exactly like return, but that forces return of more than
one level? I have no idea of what would be an elegant syntax for that,
so I will go with a function call.
Well, that's exactly what the block structure does, except that it
protects you from counting call frames (which is notoriously fragile).
It effectively provides a name for the frame you're returning to;
you're just responsible for making sure that the called function gets
the name.
function roe(v, ...)
if v then return v, ...
else nlr(2, v, ...) end
end
function foo()
local c = roe(socket.connect("localhost", 80))
roe(socket.send("GET / HTTP/1.0\r\n\r\n"))
local l = roe(socket.receive())
print(l)
return 1
end
function roe(where, v, ...)
if v then return v, ...
else where(v, ...)
end
function foo(where)
local c = roe(where, socket.connect("localhost", 80))
roe(where, socket.send("GET / HTTP/1.0\r\r\n"))
local l = roe(where, socket.receive())
print(l)
return 1
end
function call_with_ret(func, ...)
return block (p)
p(func(p, ...))
end
end
call_with_ret(foo)
--- That would all be a bit more elegant if 'where' were an upvalue in
'roe'. But that's not usually the right thing. The right thing is that
'where' is registered somewhere as the thing to call on an exception;
the registration has to be aligned with the dynamic call structure of
the program, rather than with the static lexical structure. Non-local
exits combined with an exception registry (maintained in synch with
scope finalizers) provide a simple solution to this, amongst other,
problems.