(I started writing this this morning, and there’s been quite a bit more
discussion since, but I don’t think it’s completely too late)

Thanks Paul (and others that have commented). All reasonable
considerations, and of course what the SC will be thinking about. However,
a key question.


> 4. It's a solution to one problem in the general "deferred expression"

> space. If it gets implemented, and deferred expressions are added
> later, we'll end up with two ways of achieving one result, with one
> way being strictly better than the other.


This is what confuses me. Yes, the evaluation of late-bound defaults is
technically “deferred” until the function is called, but it is a very
specific use case, with the time and namespace(s) of evaluation clearly
defined. I presume a “general deferred expression” object would provide
some flexibility on both those counts, or it wouldn’t be a general solution
at all. Sure, a general purpose deferred expression could be used to
simulate late-bound defaults, but you would still need to write extra code
or have special syntax or meaning for late bound defaults. Or have them be
poorly defined.

Could someone making this argument please propose a possible deferred
expression symtax, and how it would be used for late-bound defaults?

Otherwise, it seems completely irrelevant to the topic at hand.

Example:

Let’s say that we have:

x = deferred exp

Where deferred is a keyword, and exp is an expression which is not
evaluated right away.

So: when does exp get evaluated? Maybe when you reference x?

OK, now:

y = x

Will result in exp being evaluated.

But what namespace does it use? The one where it’s evaluated? Or the one
where it was defined? Pick one.

OK, now we have:

def fun(x = deferred exp):

Now when does expr get evaluated? If it’s when it’s used, then either the
result depends on what’s changed in the namespace where the function is
defined, or the result depends on what’s changed it the function’s
namespace.

So:

def fun(n, x = deferred n**2):
    y = x

Gives a different value for y than

def fun(n, x = deferred n**2):
    n += 2
    y = x

Or n is looked up
In the global namespace, and that could lead to some real WTF moments.

Which makes defining the default in the signature pretty pointless— reading
the signature wouldn’t give you any new info.

So then we’re back to saying that a deferred expression always gets
evaluated in the function namespace, and at the beginning of the function.
Which is, well, pretty much what the PEP is proposing.

Maybe a deferred expression gets evaluated when specifically asked to:

y = realize x

OK, but then when you look at a function signature, you’ll have no idea
when the exp will be realized — so no idea what it will do. So, back to
having to explain it in the docstring, like we do for the sentinel
 approach.



I’m sure you all think I’ve made a straw man here — something poorly
designed so I can shoot it down, but I’ve honestly done my best.

If some one can come up with a general deferred expression approach that
can also be used clearly and simply as a late bound default—please let us
know!

-CHB


-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
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/3FXELDDRVS3ZCRDR3WLJHFQMIQWY6XM2/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to