As much as I know that I should stop flaming the fires, I'd like to jump in with some of my own thoughts on the recent thread.
John Zelle and I have been somewhat cast as on opposite extremems. If you look at the pictures we draw for students to explain parameter passing and function calls, they are inherently the same. Python's model is very self-consistent and quite straightforward to explain to beginners. As I've said in an earlier post, everything comes down to understanding what an assignment statement does. Well before discussing functions, it is important for students to understand the semantics of x = 5 y = x x = 6 print y # still bound to 5 This is the issue that must be explained to students well before they broach the topic of functions. Yet once the assignment semantics is understood, the passing mechanism is a straightforward application of the assignment statement FORMAL = ACTUAL. Its the surrounding discussion that differs. We seem to be completely bogged down in the debate over the "call-by-value" and "call-by-reference" terminology. Part of the problem is that I don't believe there is a consistent, canonical source for definitions. On issue is whether this terminology is meant to describe purely the semantics of a programming language or to describe the internal implementations. This is the very first issue raised in the section on parameter passing in the Noonan/Bynum chapter of The Computer Science and Engineering Handbook (ed. Tucker). You could presumably draw a different conclusion depending on whether the focus is semantics or implementation. I certainly think that for the laymen, the verbs "call" and "pass" are more suggestive of the runtime implementation. Another problem is the hangup on a viewing a variable as a classic named memory slot, which simply is not the case in Python. When passing an argument, the issue in applying the verbs is the IMPLICIT object of that verb, that is WHAT IS BEING PASSED? If we cannot agree on what we're passing then we cannot agree on how it is passed. John has made the case that the "value" of a variable is an implicit REFERENCE, and therefore that a copy of that "value" is being passed. I disagree with forcing this characterization upon students (or programmers). Those references are not a tangible entity of the language, but an internal implementation detail in some sense. I am of the view that the "value" of a variable is the underlying object to which it is bound. Namespaces enforce a mapping from identifiers to objects. When I make a call to paint(foo), I consider the argument to be that object currently referenced by the name foo. So then the question arises how that object is communicated upon the call of a function. In this regard, I think we all agree that the information (i.e., the object) is being passed by reference rather than by value. A few other technical objections: * If we go back to the issue of what is placed on the runtime call stack, consider even a basic call sqrt(42). In a classic call-by-value language, I would reasonably expect for the binary representation of the value 42 to be placed on the call stack as the form of communication. With call-by-reference I would reasonably expect for the bits on the call stack to be an indirect reference to some memory location at which the value 42 is stored. In Python, this number will be passed at runtime as an indirect reference, not as 0000000000101010. The same is true if I make a call to data.append(sqrt(42)); the calling mechansim will not be placing the floating-point value on the call stack but rather a reference to an (unnamed) object that was the result of the nested call. I have a hard time seeing any reason for portraying this as call-by-value. * In many of the languages being discussed, the issue is that a variable is a (name,memory) binding where bits are stored in memory and the name is used syntactially to access those bits (with this mapping typically performed at compile time) This is not even the mechanism in Python. An identifier is a string. There is no specific memory address associated with than name that is used to store a pointer as its value. The identifiers in the namespace are strings that serve as dictionary keys, and those are mapped by the dictionary to those underlying pointers. Arguments portraying the by-value vs. by-reference argument as a simple test of wheter calling bar(x) allows the function to change the "value" of variable x, where value is thought of as this implicit pointer are misguided. John writes: > As I keep explaining, when the term pass-by-reference is applied to > parameter passing, it means that the formal parameter becomes a > reference to the actual variable used in the argument (more technically, > the formal parameter name is bound to the storage location of the > argument variable). That means changes to the value of the formal > parameter actually change the contents of the calling variable. Python > does not do this! You can change the state of the object that's referred > to, but you _cannot change the contents of the variable_ (what it refers > to). Even in the classic call-by-reference of the C++ example void bar(int &formal) { formal++; } A call to bar(x) cannot change the binding for the caller's variable x. It refers to a particular memory slot and the callee can not change that binding. The callee simply has access to alter the bits that are stored in that slot. Paraphrasing John's own words, you can change the state of the data that the name x refers to but you cannot make the name x refer to something else. I would say that Python meets the criteria that "the formal parameter name is bound to the storage location of the argument" if we were to agree to the fact that the argument is the underlying object (not the identifier that I presume John has in mind when he wrote "argument variable"). On that note, I'll join in support of John's conclusion: "OK, now I'm letting go of the issue." With regard, Michael +----------------------------------------------- | Michael Goldwasser | Associate Professor | Dept. Mathematics and Computer Science | Saint Louis University | 220 North Grand Blvd. | St. Louis, MO 63103-2007 _______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig