The time machine is used again! We HAVE a spelling: @functions.lru_cache()

The problem is that there's still a time/space trade-off. If you might call a (pure) function with millions of different values, you likely don't want to cache them all. The current spelling makes this configurable, but there's no universal right answer.

On Mon, May 14, 2018, 8:36 PM Steven D'Aprano <steve@pearwood.info> wrote:
I'm hoping that the arguments for assignment expressions will be over by
Christmas *wink* so as a partial (and hopefully less controversial)
alternative, what do people think of the idea of flagging certain
expressions as "pure functions" so the compiler can automatically cache
results from it?

Let me explain: one of the use-cases for assignment expressions is to
reduce repetition of code which may be expensive. A toy example:

    func(arg) + func(arg)*2 + func(arg)**2

If func() is a pure function with no side-effects, that is three times
as costly as it ought to be:

    (f := func(arg)) + f*2 + f**2

Functional languages like Haskell can and do make this optimization all
the time (or so I am lead to believe), because the compiler knows that
func must be a pure, side-effect-free function. But the Python
interpreter cannot do this optimization for us, because it has no way of
knowing whether func() is a pure function.

Now for the wacky idea: suppose we could tell the interpreter to cache
the result of some sub-expression, and re-use it within the current
expression? That would satisfy one use-case for assignment operators,
and perhaps weaken the need for := operator.

Good idea? Dumb idea?

Good idea, but you want the assignment operator regardless?

I don't have a suggestion for syntax yet, so I'm going to make up syntax
which is *clearly and obviously rubbish*, a mere placeholder, so don't
bother telling me all the myriad ways it sucks. I know it sucks, that's
deliberate. Please focus on the *concept*, not the syntax.

We would need to flag which expression can be cached because it is PURE,
and tag how far the CACHE operates over:

    <BEGIN CACHE>
        <PURE>
            func(arg)
        <END PURE>
        + func(arg)*2 + func(arg)**2
    <END CACHE>

This would tell the compiler to only evaluate the sub-expression
"func(arg)" once, cache the result, and re-use it each other time it
sees that same sub-expression within the surrounding expression.

To be clear: it doesn't matter whether or not the sub-expression
actually is pure. And it doesn't have to be a function call: it could be
anything legal in an expression.

If we had this, with appropriately awesome syntax, would that negate the
usefulness of assignment expresions in your mind?



--
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/