From: Steven D'Aprano email@example.com
Sent: Wednesday, March 5, 2014 3:25 AM
On Tue, Mar 04, 2014 at 05:05:39PM -0800, Andrew Barnert wrote:
On Mar 4, 2014, at 14:31, Greg Ewing firstname.lastname@example.org
Steven D'Aprano wrote:
What I have in my head is some vague concept that the Python
evaluation rules will somehow know when to evaluate the thunk and when to treat it as an object, which is (as I understand it) what happens in Algol.
But Algol has the benefit of static typing -- the procedure being called explicitly declares whether the argument is to be passed by name or value. Python has no idea about that at compile time.
I'm not convinced that this really matters, but for the sake of the argument let's say it does.
It's not really static typing that's key here; it's that, unless you have explicit syntax for all uses of thunks, you either need implicit type casts, and static typing is necessary for implicit type casts.
(However, as I said before, this doesn't have to be a deal-breaker. You can probably get away with making all references either immediate or delayed, so long as the syntax for doing the other explicitly isn't too obtrusive and the performance cost isn't too high. For example, if referencing a thunk always evaluates, `thunk` just creates a new thunk that will evaluate the old one, and you could optimize that into not much heavier than just passing the old one around—with a JIT, like PyPy, you could even optimize it into just passing the old one around.)
This is the main reason I think it's more productive to think of this in terms of Lisp-style quoting than Algol-style thunks.
Can you give more detail please?
I think I've already explained it, but let me try again in more detail.
A quoted expression and a thunk are similar things: ways to turn a language expression into something that can be evaluated or executed later. But there are two major differences. First, quoted expressions are first-class values, while thunks are not. Second, quoted expressions have an inspectable (or pattern-matchable) structure, while thunks do not.
You could relate that second difference to ASTs vs. code objects in Python—but since idiomatic Python does not use macros or any other generation or parsing of ASTs, it really isn't a visible difference, so the first one is more important.*
And then there's the historical difference: thunks come from static languages, quoting from dynamic languages. Together with being first-class values, this means quoted expressions need explicit but not-too-intrusive syntax not just for creating them, but also either for evaluating them, or for continuing to delay them.
So, that's why I think quoting is a more apt model for what we're trying to accomplish in this thread.
* As I mentioned before, it does actually matter for _implementation_ whether we use ASTs or code objects, at least if we want dynamic or flat in-place scoping, because the former would allow us to look up names at execution time, while the latter would not, unless we either add a LOAD_DYNAMIC opcode or compile name lookup into explicit dynamic lookup code. But as long as we define what the scoping rules are, users won't care how that's implemented.