Not all kinds of late-binding is good. Python uses dicts which has more runtime overhead than symbols, but make it hard to develop code interactively. Consider
foo.py
def foo1(x): return x+1
bar.py
from foo import foo1
def bar1(x): return foo1(x)\*2
I can modify foo.foo1 in REPL:
foo.foo1 = lambda x: x+3
but bar.bar1 will still use the old definition!
bar1 lookups foo1 via a dict which is constructed when bar is imported, so it won't be updated unless I reload all files.
So dicts are just wrong for this, there are too many of them. Symbols are basically perfect for this as they provide an easily manageable point of indirection and also much more performant.
foo.py
bar.py I can modify foo.foo1 in REPL: but bar.bar1 will still use the old definition!bar1 lookups foo1 via a dict which is constructed when bar is imported, so it won't be updated unless I reload all files.
So dicts are just wrong for this, there are too many of them. Symbols are basically perfect for this as they provide an easily manageable point of indirection and also much more performant.