I've been offline for a few days and just read this:
But you only pay the cost of the try/catch/throw when you actually use it.
Do you mean that the existence of an explicit return is recognized at compile time, so only the functions that actually contain one need to be wrapped in a try-catch? Now that I think of it, that seems like the best way to do it. I've wanted to be able to compile return-from into JS for a while...
self return: [:ret | .... ret value: foo ...].
But you only pay the cost of the try/catch/throw when you actually use it.
FWIW, I've found that the lack of explicit returns really isn't a problem, at least in the code I've written and ported so far.