On 06/12/2021 08:45, Steven D'Aprano wrote:
On Sun, Dec 05, 2021 at 05:31:58PM -0700, Finn Mason wrote:
Also, on a kind of side note, what would be a situation where early binding
is advantageous to late binding? I can't think of one off the top of my
head.
If your language only has one, early binding is better.
That's your opinion. It's not mine. Witness the Stack Overflow
questions asking why `def f(arg=[])` "doesn't work".
You can easily
simulate late binding if your language only gives you early:
def func(arg=None):
# You know the drill...
if arg is None:
arg = expression
(It's that easy because we're all familiar with the idiom. It still has
to be learned, or re-invented, by newbies.)
And if your language gives you late binding, it automatically gives you
early binding with no effort at all. Simply make the default value
something that you never change.
And you only pay the cost of call-time evaluation of the expression when
you actually need it to be evaluated at call-time.
True, late-binding has the overhead of evaluating the default value on
every call. I concede that disadvantage. I would think that in many
cases it is unimportant. But if it matters - hey, use early binding
instead. That's a reason to have both.
But to go the other way is inconvenient and annoying, requiring the use
of a global variable (or some other storage) for every parameter:
FUNC_DEFAULT_VALUE = expression
def func(arg=>None):
if arg is None:
arg = FUNC_DEFAULT_VALUE
And now, your early-bound default still pays the cost of evaluating the
sentinel expression (in this case None), but you also pay the cost of a
global lookup to get the cached value of the expression.
See above. No contortions necessary. You simply write:
def func(arg=>expression)
or if expression is expensive to evaluate:
FUNC_DEFAULT_VALUE = expression
def func(arg=>FUNC_DEFAULT_VALUE)
And you've avoided the "hack" (in quotes because not everyone agrees
that it it a hack) of needing a sentinel value.
Best wishes
Rob Cliffe
You lose encapsulation (the cached value is no longer part of the
function object) and efficiency.
Compiled languages with good optimizing compilers may be able to
optimize away some of that cost. If your language supports static
storage for functions, you can use that. But in general, without come
sort of language support, simulating early binding in a language which
only provides late binding is not as easy, convenient or efficient as
doing it the other way.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/python-ideas@python.org/message/GO56EYJ7UCRDAAHL623BSAS7GLAGOSTH/
Code of Conduct: http://python.org/psf/codeofconduct/