Specifically, in the tail-calling cases:

   g(); break;

has the unintuitive behavior of *first* breaking out of the switch-block and *then* evaluating g().

Since the difference cannot be observed (other than through growth of the control stack), I don't see that it really matters which is done first. Otherwise, many common compiler optimizations (instruction scheduling, common subexpression elimination, load/store hoisting...) are uninituitive by the same standard.

That's a fair point. I guess I'll stand down on this.

I do want to stress that we're not talking about tail calls as an optimization, but as a requirement of the language. The programmer needs to be able to rely on them, and so it needs to be well-specified exactly where the tail positions are. If that specification is complicated, it could lead to refactoring hazards, and the resulting stack growth (or overflow) could be hard to debug.

I guess my feeling is that the notion of tail position is just cleaner when it doesn't involve control operators like `break' and `return', and that's one of the reasons I like the idea of a `lambda' form that doesn't use `return'.

But I won't argue against having more tail positions in forms like `switch'. So much the better, even if it's messy.

Dave

_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to