On Fri, Sep 23, 2016 at 5:54 AM Chris Angelico <ros...@gmail.com> wrote:

> On Fri, Sep 23, 2016 at 12:35 PM, Steven D'Aprano <st...@pearwood.info>
> wrote:
> > The straight-forward and simple way of writing a recursive spam()
> > function surprises beginners, but they might go years or their entire
> > career without running into a situation where they are caught by
> > surprise. After all, it is rare for productuon code to rename functions,
> > and rarer still to do it to recursive functions:
> >
> >     func = spam
> >     spam = something_else()
> >     func()  # why does the recursion not work???
> >
> > In production code, that sort of thing almost never happens.
>
> There's actually one very common technique involving rebinding functions.
>
> @count_calls
> def mergesort(lst):
>     mid = len(lst) // 2
>     if not mid: return lst
>     return merge(mergesort(lst[..mid]), mergesort(lst[mid..]))
>
> *Obviously* this is recursive. But if you used some magic that said
> "call the function that's currently being called", you'd be bypassing
> the count_calls decoration (which would presumably work by creating a
> wrapper function). Yes, it may defeat some potential optimizations (eg
> tail recursion optimization), but it enables all this flexibility.
>
> So we _need_ to have this kind of rebind available, and not just for
> experts.
>
>
I think you are mixing levels of abstraction because you know how this is
implemented. The user only sees "A function named mergesort decorated by
count_calls". She does not see "A function named mergesort passed to a
higher order function named count_calls whose result is bound into the
variable mergesort". Even if the latter is exactly what happens,
declaratively the former is more accurate by intention.

Ideally, the calls to mergesort will rebind to this _decorated_ function.
not to the mutable global variable. Again, the argument that it will be
very hard to implement it in a different way, or that is will break things,
is a very strong argument, and I am not confronting it.

> In the meantime, I'll usually just write my recursive functions the
> > old-fashioned normal way.
>
> As will I. Of course, people are welcome to work differently, just as
> long as I never have to write tests for their code, or refactor
> anything into a decorator, or anything like that. I want the
> POWAH!!!!! :)
>

As will I, simply because the old-fashioned way is more readable. And I
will sadly accept the fact that I can't be 100% sure what's function is
called at runtime. But _some_ people (medium-level, Steven, whose main
language is probably not Python) will not even know this is the case.

Tests are important and could have reworked into the system (through
inspect, or by using a special import which allow monkey patching). I can't
see why the ability to test must remain in production.

Elazar
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to