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/

Reply via email to