> But you haven't refuted (or even engaged with) my main point at all.
OK. Your main point (now that you have shifted the goalposts) seems to be that argument passing induces a binding of the parameter name to the argument value, yes?
In the abstract, this point is meaningless since it applies equally to every other programming language. In this C function:
void foo(int x, float y, char *z) { ... }
the C compiler also has to manage bindings from variable names to the locations where their values are stored. It needs that information to find the correct values in registers or (just like in Python) on the stack.
In the concrete, the point is also meaningless since those bindings do not involve dictionaries as you seem to think. For positional functional arguments, loooong before the call takes place, the bytecode compiler resolves names to stack indices, and the variables are accessed through those. Just like C can access arguments passed on the stack using constant offsets from the stack pointer.
Here is the code for the normal call fast path:
https://github.com/python/cpython/blob/62be74290aca26d16f3f5...
f = _PyFrame_New_NoTrack(tstate, co, globals, NULL);
if (f == NULL) {
return NULL;
}
fastlocals = f->f_localsplus;
for (i = 0; i < nargs; i++) {
Py_INCREF(*args);
fastlocals[i] = *args++;
}
result = PyEval_EvalFrameEx(f,0);
This sets up a stack frame for the callee (on the heap, yes), then copies the arguments (which are pointers to PyObject) into slots in that stack frame numbered consecutively from 0.
Access to these arguments inside the callee is via the LOAD_FAST bytecode instruction:
https://github.com/python/cpython/blob/master/Python/ceval.c...
case TARGET(LOAD_FAST): {
PyObject *value = GETLOCAL(oparg);
...
which uses the GETLOCAL macro:
https://github.com/python/cpython/blob/master/Python/ceval.c... #define GETLOCAL(i) (fastlocals[i])
Nowhere are name-value bindings allocated dynamically in this normal case. Python
does perform dictionary manipulation for keyword args, but not for positional ones. For normal positional arguments, the mechanism is exactly equivalent to a C (or whatever) compiler pushing arguments onto the stack. Local variables are
exactly what you claimed that they were
not, namely names for storage locations (stack slots).
I'm done with this thread now.