On Sun, May 24, 2020 at 12:36 PM Alex Hall <alex.moj...@gmail.com> wrote:

> OK, let's forget the colon. The point is just to have some kind of
> 'modifier' on the default value to say 'this is evaluated on each function
> call', while still having something that looks like `arg=<default>`. Maybe
> something like:
>
>      def func(options=from {}):
>

I worry so very little about this issue of mutable defaults that this
discussion has trouble interesting me much.  It's a speed bump for
beginners, sure, but it's also sometimes a sort of nice (but admittedly
hackish) way of adding something statefull to a function without making a
class.  On the other hand, I mostly thought it was cool before generators
even existed; nowadays, a generator is more often a useful way to have a
"stateful function" (yes, I know there are some differences; but a lot of
overlap).

The pattern:

def fun(..., option=None):
    if option is None:
        option = something_else

Becomes second nature very quickly.  Once you learn it, you know it.  A
line of two of code isn't a big deal.

But this discussion DOES remind me of something much more general that I've
wanted for a long time, and that has had long discussion threads at various
times.  A general `deferred` or `delayed` (or other spellign) construct for
language-wide delayed computation would be cool. It would also require
rethinking a whole lot of corners.  I think it would address this mutable
default, but it would also do a thousand other useful things.

Much of the inspiration comes from Dask.  There we can write code like this
simple one from its documentation:

output = []for x in data:
    a = delayed(inc)(x)
    b = delayed(double)(x)
    c = delayed(add)(a, b)
    output.append(c)
total = delayed(sum)(output)

However, in that library, we need to do a final `total.compute()` to get
back to actual evaluation.  That feels like a minor wart, although within
that library it has a purpose.  What I'd rather in a hypothetical future
Python is that "normal" operations without this new `delayed` keyword would
implicitly call the .compute().  But things like operators or most function
calls wouldn't raise an exception when they try to combine DelayedType
objects with concrete things, but rather concretize them and then decide if
the types were right.

As syntax, I presume this would be something like:

output = []
for x in data:
    a = delayed inc(x)
    b = delayed double(x)
    c = delayed add(a, b)
    output.append(c)

total = sum(outputs)  # concrete answer here.

Obviously the simple example of adding scalars isn't worth the delay
thing.  But if those were expensive operations that built up a call graph,
it could be useful laziness.  Or for example:

total = sum(outputs[:1_000_000)  # larger list, don't compute everything

-- 
The dead increasingly dominate and strangle both the living and the
not-yet born.  Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
_______________________________________________
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/IDRLUHRALKZOWCDZPQGB4PGPZU5ECN5G/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to