Python is more of a lisp. The assignment semantics are different to C. Actually, you're letting the name "a" point to the newly created object.
In C, a variable is a memory position you can fill and point to.
In Python, a variable is a name that points to a memory position.
Similarity to C is no accident here, since the lexical scoping concepts in Lisps like Scheme and CL, as well as in C, both trace back to Algol.
Classic Lisp global/dynamic variables may store a global value a "value cell" which is closely tied to the symbol itself (perhaps stored in it).
And in that sense, C assignment and Lisp assignment are different beasts. Mainly in that - again in the semantics of the high-level description - "memory reservation" in C happens when we declare the left-hand side of an assignment and in Lisp it happens when we construct the right-hand side.
Though if you can show me a mainstream Lisp where the assignment works like setting a memory cell and not like a bind, I'm happy to be proven wrong.
The right hand side reserves memory only in the sense that some heap object is allocated (if that is the case), but that is secondary to the assignment; and that is the same as C also, as in:
f = fopen(...); // right hand allocates stream; pointer moves into variable.
> if you can show me a mainstream Lisp where the assignment works like setting a memory cell and not like a bind, I'm happy to be proven wrong.The mainstream Lisps clearly separate binding from assignment.
(let (x) ;; x refers to a freshly allocated cell (nil-initialized, in Common Lisp)
...
(setq x 42) ;; cell is clobbered, replacing nil with 42.
...)
Some of the terminologly used in the specifications is a bit confused. For instance, Common Lisp says say that:1. A variable is a "binding in the variable namespace" (Glossary)
2. A binding is an association between a name and a value (Glossary)
3. Yet, the description of SETQ uses language like: "First form1 is evaluated and the result is stored in the variable var1".
4. LET is described like this "let and let* create new variable bindings and execute a series of forms that use these bindings". No binding creation semantics is mentioned for SETQ.
Results can only be stored in storage places; nothing can be stored in an "association between a name and a value", unless that association is actually set up through a memory cell: the name refers to a location and the location holds a value. SETQ isn't described in terms of breaking an old binding and setting up a new one..
In the case of dynamic and global variables, there is a term "value cell" which the Glossary defines: like this: "The place which holds the value, if any, of the dynamic variable named by that symbol, and which is accessed by symbol-value. "
Let's turn our attention to Scheme. R7RS says in 3.1. Variables, syntactic keywords, and regions this:
"An identifier can name either a type of syntax or a location where a value can be stored."
and:
"An identifier that names a location is called a variable and is said to be bound to that location."
"The value stored in the location to which a variable is bound is called the variable’s value."
The next sentence is a kicker, and can be regarded as a criticism of the ANSI CL definition of binding:
"By abuse of terminology, the variable is sometimes said to name the value or to be bound to the value."
If you think that Lisp variables are bindings to values, then according to the Scheme maintainers, you've fallen victim to abuse of terminology. :)
Thanks!
But if l does support __iadd__, then l += r becomes l.__iadd__(r).
This behavior for list and tuple is familiar from regular local variables. Together with the fact that obj.x = ... always means "create or rebind an instance variable" never "rebind the A.x class variable", I think the example is less surprising.
> # tuples are immutable and don't have "+="
What do you mean? Because it looks to me tuples have "+=":
I get that tuple is immutable so you're actually creating a new tuple and shove it back into variable a, but it does not conflict with "having += operation".