lua-users home
lua-l archive

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


On Mon, Nov 21, 2011 at 21:42, Daurnimator <quae@daurnimator.com> wrote:
> That errors should be resumable:
> - for warnings: sometimes you just want to ignore them and continue
> - some errors can be recovered with user input
>
> So I had a grand idea: re-implement errors as we know them in lua;
> with coroutines!
>  - error raising functions (such as error and assert) are replaced
> with coroutine.yield
>  - pcall just becomes a wrapper around coroutine.create
>
> I went and made a small library to try it; and it works great!
> https://gist.github.com/1384850
>
> A few problems occured along the way:
>  - varargs + variable length return values are a bitch: so many
> functions! everything has to be a tailcall too; or you blow the stack.
>  - xpcall becomes slightly incompatible with existing handlers: you
> are no longer running in the error'd thread in the error handler: the
> thread that had the error is passed in (and you can use this parameter
> to get information with debug.getinfo()/debug.traceback()/etc
>
> A few realisations came about:
>  - This wasn't only a system for adding resumable errors; it is a good
> way to raise and catch errors overall
>  - You get yielding over pcall boundarys for free
>  - The standard lua error system is no longer needed: adding something
> like this to the standard distribution may really simplify thing: “A
> designer knows that he has achieved perfection not when there is
> nothing left to add, but when there is nothing left to take away”
>
>
> What do you think?
> Would you use something like this in your own code?
> Should the error system as we know it be replaced?
>
> D
>

Funny, I had a very similar idea the other day:

#!/usr/bin/env lua
local errhandler = coroutine.create(function(what)
	while true do
		io.stderr:write("Error: " .. what .. '\n')
		what = coroutine.yield(what ~= "It's broken")
	end
end)
function throw(what)
	local ok, stat = coroutine.resume(errhandler, what)
	if not ok then error("Error in error handler: " .. tostring(stat)) end
	if not stat then error("Unrecoverable error: " .. tostring(what), 2) end
end

pcall(function()
	print("one")
	throw("I goofed")
	print("two")
	throw("It's broken")
	print("this should never be reached")
end)
print("three")
throw("It's broken")
print("this should also never be reached")

If it were possible to kill coroutines, the error handler could even
do that for severe errors. (In your own applications, you could just
have a table of coroutines that run one after another, and just remove
it from there...)


Related: I'd love a standardized warning system in Lua. It could be as
simple as:
function warn(...)
    local here = debug.getinfo(2, 'Sl')
    print(("Warning: %s:%d:"):format(here.short_src, here.currentline), ...)
end

and then you just replace it with your own function if you want to
handle warnings differently.

-- 
Sent from my toaster.