On Thu, 17 Aug 2017 11:37 pm, Ben Bacarisse wrote: > What goes wrong when someone thinks of Python as passing by value but > the value of an expression is an object reference?
Lots. Because even if people *think* about call by value where the value is an invisible reference to the actual value, that's not how they talk, because it's too hard. Look at Scott Stanchfield's extremely influential post. It is *not* called: "Java is call by value where the value is an invisible object reference, dammit!" http://javadude.com/articles/passbyvalue.htm and consequently people who don't read or understand the *entire* post in full take away the lesson that "Java is call by value, dammit!" So how do we distinguish between languages like Java and Python and those like C and Pascal which *genuinely* are call by value, and do exhibit call by value semantics? For example, in Pascal, if you declare an array parameter without specifying it as "var", the compiler will copy the entire array. Java does not do that. Python does not do that. C doesn't treat arrays as first class values, so you can't pass an array as argument. You can only pass a pointer to the start of the array. But you can declare arbitrarily big structs, and they are copied when you pass them to functions. Java objects are not. Despite Scott's insistence that Java is exactly the same as C, it isn't. If we claim that Python is call by value, without specifying the proviso "if you consider the value to be the invisible reference to the actual value" every time, we risk misleading others into wrongly inferring that Python is "call by value" and you shouldn't pass big lists to functions because then they will be copied and that's inefficient. Or people will be confused by the behaviour of Python, and decide that maybe it is only call by value when you pass an immutable object like a string or int, and is call by reference when you pass a mutable object like a list or dict. Many people have done that. Imagine this conversation: * * * "I was reviewing your code, and in module spam.py I don't understand what value the x variable has." "I don't know. It's something implementation dependent." "What do you mean?" "It depends on the interpreter. In CPython the value will be a pointer. Something like an address 0x1234abcd." "But Python doesn't have pointers." "Okay, call it a reference then. Whatever the implementation uses to point to objects." "I don't care about the Python implementation, I want to know the value of x." "I told you. It's some unknown and unknowable reference or pointer to an object." "Okay. Given x=1, what's the value of x?" "How do I know? It depends on the implementation. Something like 0x93a80f16 I guess. Why do you care about the value?" * * * Obviously this isn't going to happen. Nobody actually thinks like this. Given x=1, we all agree that the value of x is 1, not some invisible, unknown, unknowable, implementation-dependent reference. Instead they have to juggle two mutually contradictory meanings of value in their head, and try to guess which one is meant at any point. Sometimes the value of x is 1, and sometimes it is the invisible reference, and because that is usually implied rather than explicit, there's always room for confusion and misunderstanding. This whole thing is unnecessary. It is no easier to learn that: "Python is call by value, where the value is an invisible object reference" than it is to learn that: "Python is call by object sharing". Either way, you have to learn what it means, otherwise it might as well be gobbledygook: "Python is whargle bargle by wazit, where the wazit is fizzbit wacker p'toing". The terminology has been around for forty years. It was invented by Barbara Liskov, one of the pioneers of OOP, the same person responsible for the Liskov Substitution Principle. So its not like it is some obscure term invented by "just some guy on the internet". -- Steve “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