Full disclosure, I haven’t read the book or watched the film, but the name (pun intended)
gets across the point I want to make about python names. (Note how I use the term names
and not variables or references, which will strike a chord in a few minutes).
On the C side of things, you have call-by-value, and on the Java/ECMAScript side of the world,
you have call-by-reference. But python, is sly, and while on the surface you’ll think python is
call-by-reference, it’s a different barnacled monstrosity. Python is what you might call,
call-by-name.
Here’s an innocuous piece of code, which for some inexplicable reason doesn’t produce the expected
output:
Despite the code being synthetic, it underscores an important point. In this particular example,
the output on the console is [1,2] and not [1]. How on earth is that possible, you ask?
Well, the answer to this mystery lies in the fact that python is call-by-name.
In the call-by-name model, a name (or a variable in common parlance) is bound to an object. In the main,
arr is bound to the object [1,2]. Initially in mutate, ls is bound to the same object [1,2]
- note, how we say bound to an object and not a reference to a memory location, unlike C/Java/ECMAscript
- but, on the very first line of mutate, we bind ls to a new object [], and hence forth the binding
of [1,2] is hidden from mutate. Any changes to ls will not be reflected back to arr as they are bound
to different objects.
While this might seem pedantic, and left to language purists. This erudite fact can manifest in hard to find bugs. For example, the following code has a surprising output:
The output of this code is as follows:
The second conditional becomes a no-op as arr won’t be mutated once it’s length is greater than 5. Ipso facto,
call-by-name is evident right now, but in longer methods its to discern and impossible to debug.
So, next time recall that python does call (me) by (your) name.