Q: Can we use fibers for error-handling? The goal here is to avoid adding support for exception handling if we're already going to support fibers. A potential bonus would be being able to have restartable error-handling. The general idea is that instead of putting code in a "try" block, you throw it onto a new fiber. If an error occurs, that fiber is paused, and returns control back to the spawning fiber. The parent fiber can then decipher the error and either abandon the fiber, or try to fix the error and resume somehow. The first question is what kinds of errors is this useful for. For things like parsing strings where failure is common and error-handling needs to be lightweight, I think using fibers is too heavy, both in performance and code. A better answer there is to lean on dynamic typing and return null on parse failure. On the other hand, it might be nice to be able to resume here if the code that provided the string is far away and you don't want to have to manually propagate the error out. Programmatic errors like invalid argument types should halt the fiber but the programmer will not want to resume that at runtime. Using the mechanism here is fine since it would then dump a stack trace, etc. But it won't take advantage of resuming. Resuming is probably useful for things like IO errors where the error can't be easily predicted beforehand but where you may want to handle it gracefully. For example, if a file can't be opened, the caller may want to wait a while and try again. -- After thinking about it, maybe resuming is a bridge too far. Erlang's model is that a failure just kills the process. I'll note that Erlang does have try and catch, though. The goals for error-handling in a scripting language are: 0. Have simple semantics and implementation. 1. Make it easy for developers to track down programmatic errors so they can fix them. This means bugs like wrong argument types should fail immediately and loudly, and should provide context (a callstack) about where the error occurred. 2. For runtime errors like parsing an invalid string or opening a missing file, the program should be able to easily detect the error at handle it. 3. It *may* be useful for programmers to be able to trap all errors and try to keep the program alive, or at least log the error in a meaningful way. When you have user-defined scripts, or a lot of code, or code authored by non-technical people, it's nice if a failure in one part can be reported but not take down the entire system. Two close-at-hand examples: - The REPL. A bug in code in the REPL shouldn't kill the whole REPL session. - The test framework. In order to write tests in Wren that test programmatic runtime errors, we need to be able to detect them and output something. The test runner could just parse the error output when the entire process dies, but that means you can only have one error test per test file. Given those, I'm thinking: 1. Programmatic errors take down the entire fiber and dump a callstack. Normally, they will also take down the parent fiber and so on until the entire program goes down. 2. Runtime errors return error codes (or null). Things like parsing a string to a number, etc. should just return an error that you are responsible for handling. 3. When handing off control to a fiber, there is a "guarded run" method that will run the fiber. If it fails with a programmatic error, the invoked fiber dies, but the parent does not. It gets the callstack and error as some sort of object it can poke at.