2 ms·
That's true, although 'return' will only pop one frame off the stack whilst 'throw' will keep going until it finds a handler. Hence 'return' has a more predicta
by chriswarbo 9y ago
That's true, although 'return' will only pop one frame off the stack whilst 'throw' will keep going until it finds a handler. Hence 'return' has a more predictable/consistent behaviour, and less context-dependence.
- gpderetta 9y ago> although 'return' will only pop one frame off the stack Unless it was a tail call... Really, throw and return are quite similar, both invoke an externally provided continuation and abandon the current one.
- gpderetta 9y agoedit: but yes, of course I'm being pedantic.
- chriswarbo 9y agoHeh, I actually wrote something about continuations, then decided against it. I was going to say: In a pure CPS setting, the caller's "only" responsibility is to give the right arguments (in scare quotes because getting a continuation right is usually trickier than the "plain" values usually given to functions). In languages with functions, the caller is also responsible for handling/ignoring any return value and carrying out any subsequent computations, if the procedure returns. In languages with exceptions, the caller is also responsible for handling/passing-on any exceptions. Out of these three sorts of language, my current preference is for the second. It's probably fair to say that most procedures in a codebase will return a value (i.e. they're not continuations) and will not throw an exception (they're exceptional, after all). Hence it seems empirically desirable to allow `return`: it alters the semantics from a pure CPS scenario to one where we must always be vigilant that a procedure may return; but since most procedures (in such languages) return, that's not an edge case (in fact it's continuations, procedures without `return`, that are rare!); hence the benefits seem worth the cost. When `throw` is introduced, we again must be vigilant when we're calling procedures. However, since most procedures don't `throw`, the benefit of having this ability is less than that of `return`. Also, since there may be many occurrences of `throw`, with different exception types, the cost of looking out for and handling these is greater than for `return`. Hence my (current) opinion that `return` is very much a "good GOTO", whilst `throw` is a "bad GOTO" :) Then we get `call-cc`... ;)
- gpderetta 9y agoThe trick with throw is, of course, assuming that any procedure may potentially throw, except for a selected 'always succeeding' few. So avoid any non-local mutation and for those that are unavoidable take a transactional approach. 'call-cc', the control operator from hell that puts 'spaghetti' goto to shame.