On Sun, 31 Jul 2016 02:01 pm, D'Arcy J.M. Cain wrote: > On Sun, 31 Jul 2016 13:32:16 +1000 > Steven D'Aprano <st...@pearwood.info> wrote: >> Many beginners make the mistake of writing: >> >> mylist = mylist.sort() >> >> or try to write: >> >> mylist.sort().reverse() >> >> If we had procedures, that would be an obvious error (possibly even a >> compile-time syntax error) instead of a perplexing source of mystery >> bugs. > > While neither is a syntax error, the latter is definitely a run-time > error: > >>>> mylist.sort().reverse() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: 'NoneType' object has no attribute 'reverse'
Hence my description of it as a perplexing source of mystery bugs. How did mylist suddenly turn into None? Well, it didn't, but it sure looks like it did, for those who didn't realise that sort() is intended to be used *as if* it were a procedure with no return value. If it *actually* had no return value, Python could give a more useful error message: ProcedureError: list.sort() has no return value as soon as the interpreter tries to push the non-existent return value onto the stack. Python can't do that, because None is an ordinary object line any other. There's no practical way for Python to distinguish (whether at compile-time or run-time) None as an ordinary object from None as a stand-in for "no object at all". In practice, for moderately experienced programmers, the difference is minor and most people quickly learn how to debug "None object has no attribute" exceptions. But for a teaching language where we want to be stricter about the dichotomy of: - subroutines that transform values (functions); and - subroutines with side-effects (procedures) its a little sub-optimal. -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list