4 ms·
> I'm not even sure what the result of a looping expression should be This is one of the reasons I like having proper tail calls be part of a language specific
by tonyg 12y ago
> I'm not even sure what the result of a looping expression should be
This is one of the reasons I like having proper tail calls be part of a language specification, incidentally :-)
Reason being that loops are then simple derived constructs, and their meaning (as expressions and otherwise) follows from their definition.
In the specific case of "while", the value of a while-loop-like form would usually be null/void, because of the one-armed-if it expands into.
Regarding implicit return values: in your example, the sayHi method would naturally return null if IO.write returned null, even with implicit return values. Having a strong library convention that imperative procedures return null seems to prevent programmers from trying to rely on the results of imperative procedures, even where implicit return values are part of the language. My support for this claim is only anecdotal; it comes from working with programs written in Racket, which has both implicit return values and a strong convention of returning void from imperative procedures.
- munificent 12y ago> In the specific case of "while", the value of a while-loop-like form would usually be null/void, because of the one-armed-if it expands into. Right, which doesn't make it very useful as an expression. > Having a strong library convention that imperative procedures return null seems to prevent programmers from trying to rely on the results of imperative procedures I have the opposite feeling (possibly because Wren doesn't have implicit returns). Since library calls are expressions, they may as well return something useful when possible. For example IO.print() returns its argument. That's handy for debugging the result of an intermediate expression. Say you've got: someMethod(anotherOne(arg)) And something weird is going on. Giving IO.print() a return value lets you inject it in the middle: someMethod(IO.print(anotherOne(arg))) without having to hoist the subexpression out. > My support for this claim is only anecdotal; it comes from working with programs written in Racket, which has both implicit return values and a strong convention of returning void from imperative procedures. Yeah, that makes sense. I think the important idea is to be consistent.