Deep vs. shallow copy?

Rustom Mody rustompmody at
Thu Mar 13 04:09:25 CET 2014

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

For an old Algol/Fortran programmer it may be a worthwhile read considering
Backus invented Fortran :-)

More information about the Python-list mailing list