I think the example that Steven gave, and Stephen
approximately repeats is good.
def
func(items=[], n=later len(items)):
items.append("Hello")
print(n)
func()
> I guess Chris will say 0 and David will say 1, but I
might be wrong about either of them.
This is correct. And even though using a (soft)
keyword like this gets me to -0, the semantics I want indeed
are different. I only want the binding to be evaluated when it
is referenced. If it never gets referenced, the compassion
time asked side effects are skipped.
Of course, the first line of the function body
could be `n = n`. But adding that line isn't so much different
from starting with `if n is None: n = ... `
As to Stephen's comments on not having used the
"evaluate on reference" pattern, that's pretty much not having
used dask.deferred.
The difference is that with Dask (or Haskell)
everything stays lazy until you explicitly call `.compute()`
on something in the DAG of operations. I'd prefer not to need
that.
But then my not-a-proposal would need a way to
have "a reference that isn't a reference". I think the same
keywords works.
def
func(items=[], n=later len(items)):
items.append("Hello")
n = later
n**3 # n remains lazy
# ...
more stuff
print(n)
# actually evaluate the cube of length
Chris
wants syntax for the common pattern
def foo(arg_with_new_empty_list_default=None):
if arg_with_new_empty_list_default is None:
arg_with_new_empty_list_default = []
# do stuff
I can't really guess how useful the "use point" version
would be. It's not a pattern I've used, I use a
zero-argument function very occasionally but I can't
recall a case where I used a lambda