On Fri, Sep 11, 2015 at 4:13 AM, Steven D'Aprano <st...@pearwood.info> wrote: > Sometimes they might be. But in general, I think it is meaningless to expect > a imperative command to have a return result. The whole point of an > imperative command is that it operates by side-effect. > > For example, what would `del x` return if it were an expression instead of a > statement? I can think of two reasonable alternatives, but both feel a bit > wrong to me. > > (1) Return True if x was successfully unbound, False if it wasn't. Except > that raising an exception seems more Pythonic, in which case returning True > seems redundant. It will *always* return True, unless there's an exception. > So why bother? We only bother because there's no way to *not* return a > result if "everything is an expression". > > (2) Return None, like functions do by default. But again, it only returns > None, not because None is a meaningful thing to return, but because we > don't actually have a way to say "it doesn't return anything".
Yes, or: (3) Return the old value that x contained, the way dict.pop() does. That makes it a "destructive retrieval" rather than simply a destruction operation. > Or os.abort. The docs for that say: > > Help on built-in function abort in module posix: > > abort(...) > abort() -> does not return! > > Abort the interpreter immediately. This 'dumps core' or otherwise fails > in the hardest way possible on the hosting operating system. > > > So, what would os.abort() return, if everything is an expression? Since this is in the os module, and is thus a thin wrapper around lower-level operations, I could imagine it returning an error code (the way the C-level exec functions do - if they succeed, they don't return, but if they fail, they return an error number); in Python, it'd be best to have it either abort the process (and thus not return), or raise an exception (and thus not return). But abort functions are a rarity. It's not a problem to have a rule "all functions must return something" (as Python does), and then have functions that never actually use the normal return path: def raise_(exc): raise exc raise_stopiteration = iter([]).__next__ raise_typeerror = lambda: ""() Calling one of these functions is *syntactically* an expression, but at run time, it'll never actually get as far as producing a value. If it's at all possible for the operation to, based on run-time information, NOT abort, then it absolutely has to be able to return. > Because that's the definition of an expression in this context. An > expression is evaluated to either return a result, or raise an exception. I'd define it more simply: An expression always produces a result. It's possible that, during the evaluation of an expression, an exception will be raised; if that happens, evaluation stops. Doesn't matter whether the expression itself caused that, or if an OS-level signal did (eg triggering KeyboardInterrupt), or if the expression was "yield 1" and an exception got thrown in. But yes, an expression is something that generates a result; a statement isn't. ChrisA -- https://mail.python.org/mailman/listinfo/python-list