
On Tue, Jan 19, 2016 at 08:47:28AM -0800, Guido van Rossum wrote:
I think it's reasonable to divert this discussion to "value capture". Not sure if that's the usual terminology, but the idea should be that a reference to the value is captured, rather than (as Python normally does with closures) a reference to the variable (implemented as something called a "cell").
If I understand you correctly, that's precisely what a function default argument does: capture the current value of the default value expression at the time the function is called. This has the side-effect of exposing that as an argument, which may be underdesirable. partial() can be used to work around that.
(However let's please not consider whether the value should be copied or deep-copied. Just capture the object reference at the point the capture is executed.)
The best syntax for such capture remains to be seen. ("Capture" seems to universally make people think of "variable capture" which is the opposite of what we want here.)
If I recall correctly, there was a recent(?) proposal for a "static" keyword with similar semantics: def func(a): static b = expression ... would guarantee that expression was evaluated exactly once. If that evaluation occured when func was defined, rather than when it was first called, that might be the semantics you are looking for: def func(a): static b = b # captures the value of b from the enclosing scope Scoping rules might be tricky to get right. Perhaps rather than a declaration, "static" might be better treated as a block: def func(a): static: # Function initialisation section. Occurs once, when the # def statement runs. b = b # b on the left is local, b on the right is non-local # (just like in a parameter list) # Normal function body goes here. But neither of these approaches would be good for lambdas. I'm okay with that -- lambda is a lightweight syntax, for lightweight needs. If your needs are great (doc strings, annotations, multiple statements) don't use lambda. -- Steve