On Fri, Feb 17, 2017 at 06:06:26PM -0500, Joseph Hackman wrote: [...] > I think it would be key, like async/await, to narrowly define the scope in > which the word delayed functions as a keyword.
The PEP makes it clear that's just a transition phase: they will be turned into proper keywords in Python 3.7. https://www.python.org/dev/peps/pep-0492/#id80 Python has had "pseudo-keywords" in the past, like "as": [steve@ando ~]$ python2.5 -c "import math as as; print as" <module 'math' from '/usr/local/lib/python2.5/lib-dynload/math.so'> and it is my understanding that the core developers dislike this sort of thing. As do I. You shouldn't count as getting the same special treament as async/await. Maybe you will, maybe you won't. > > A new keyword means it can't be back-ported to older versions, and will > > break code. > > > > > async and await both work fine, for the reasons listed above. You're missing the point: code that uses async and await, whether as pseduo-keywords or actual keywords, cannot easily be backported to Python 3.4 or older. If Python introduces a new built-in, say Aardvark, then it can be back-ported: try: Aardvark except NameError: from backport import Aardvark No such thing is possible for new syntax. So that counts as a disadvantage of new syntax. Are we positive that there *must* be new syntax to solve this problem? (I think probably so, but it still counts as a disadvantage: that means that the usefulness is reduced.) > > > Unlike 'lambda' which returns a function (so the receiver must be > > > lambda-aware), delayed execution blocks are for all purposes values. The > > > first time the value (rather than location) is read, > > > > What counts as "reading" a value? Based on your example below, I can't > > tell if passing the object to *any* function is enough to trigger > > evaluation, or specifically print is the magic that makes it happen. > > So far I'm going with pretty much anything that isn't being the right-hand > of an assignment. So coercion to different types, hashing (for use as a key > in a dict or set), __repr__, etc would all be covered, as well as identity > and comparisons. i.e.: [...] That will make it pretty much impossible to tell whether something is a delayed "thunk" or not, since *any* attempt to inspect it in any way will cause it to reify. Maybe that's what we want. > > That's easily done by having the "delayed" keyword cache each expression > > it sees, but that seems like a bad idea to me: > > > > spam = delayed: get_random_string() > > eggs = delayed: get_random_string() # the same expression > > > > spam.upper() # convert to a real value > > > > assert spam == eggs # always true, as they are the same expression > > > > Since spam and eggs are two different instances of delayed expression, each > one would be evaluated separately when they are read from (as operands for > the equals operator). So no, even without the spam.upper(), they would not > match. Earlier we talked about delayed *expressions* always generating the same value, now you're talking about *instances* rather than expressions. It makes sense to have keep the standard Python object semantics, rather than have the value of a delayed thunk cached by the textual expression that generated it. > > I think it is better to stick to a more straight-forward, easily > > understood and debugged system based on object identity rather than > > expressions. > > > > > The caching means that: > spam = delayed: calculate(1) > eggs = spam > > eggs == spam would be true, and calculate would have only been called once, > not twice. That's not caching, that's simple identity. That's how assignment works in Python, delayed calculation or not. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/