On Thursday, March 13, 2014 4:37:53 AM UTC+5:30, Steven D'Aprano wrote: > On Wed, 12 Mar 2014 15:29:59 +0000, Alex van der Spek wrote:
> > Having been taught programming in Algol60 Python still defeats me at > > times! Particularly since Algol60 wasn't very long lived and what came > > thereafter (FORTRAN) much worse. > I'm not really familiar with Algol, but I do know Pascal, and you should > think of the append method to be like a Pascal procedure. Because Python > doesn't have true procedures, it follows the convention that returning > the special object None signals the intention to return nothing at all. > Hence your example below: Yes... Algol I dont know. But to the extent that it corresponds to Pascal the following may help. Pascal is remarkably clean and cleaner than what came before -- Lisp -- and after -- C, all its derivatives, python... almost everything. First off there are expressions and statements, and no messing with the distinction. C started laissez-faire. No void, just default functions intended to be used as procedures to int. This was problematic to enough people that void was introduced soon enough. But its still messy: An assignment like x = 3 is both an expression and (like) a statement. It is mostly used as a statement by appending a semicolon. It can also be used as an expression as in y = x = 3. Try explaining this to a first year class and you'd know what a mess it is. For the most part if you think youve got it you probably havent. Python is in some respects worse than C, in some better. Its better in that assignment statements are not re-purposeable as expressions. Its worse in that procedures are simulated by None returning functions -- this means syntax errors which C would give when using a void function as an expression, you wont get in python. On the whole, whether your language supports it or not, its best to think of the world as separated into actions and values. Call the action-world the 'imperative' world. Call the value-world the 'functional' world ('declarative' would be better but 'functional' is too entrenched). [Following table meant to be read with fixed (courier) font] | | Imperative | Functional | | Language entity | Statement | Expression | | Denote (and think with) | Action | Value | | Abstracted into | Procedure | Function | | Atoms are | Assignment | Constant/Variable | | Data Structures | Mutable | Immutable | | Loop primitive | Recursion | Iteration | | World is | In time | Timeless (Platonic) | Generally mixing these two worlds is necessary for any non-trivial programming but is commonly problematic. Your error was to use a functional form -- list comprehension -- and embed an imperative construct -- row.append -- into that. This is always a gaffe Legal mixing is done thus Expression -> Statement by putting the expression on the rhs of an assignment Statement -> Expression by putting the statement(s) into a function While most programmers think this unproblematic, Backus' widely-cited Turing Award lecture is devoted to showing why this is a problem http://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf For an old Algol/Fortran programmer it may be a worthwhile read considering Backus invented Fortran :-) -- https://mail.python.org/mailman/listinfo/python-list