[Python-ideas] Return for assignment blocks

Steven D'Aprano steve at pearwood.info
Thu Oct 25 16:29:55 EDT 2018


On Thu, Oct 25, 2018 at 08:44:44AM -0400, Calvin Spealman wrote:
> On Wed, Oct 24, 2018 at 4:41 PM Steven D'Aprano <steve at pearwood.info> wrote:
[...]
> > I *think* you are proposing the following syntax. Am I right?
> >
> >
> > return def (func):
> >     # body of func
> >
> > which is equivalent to:
> >
> > def func:
> >     # body of func
> > return func
[...]
> > Aside from saving one line, what is the purpose of this?
> >
> 
> The point is not saving a line or typing, but saving a thought. Expressing
> the intent of the factory function more clearly.

I don't find that it expresses the intent clearly. Perhaps because I 
have read, and written, many factory functions that post-process the 
inner function in some fashion, to me creating the inner function is 
just one step out of possibly many steps, no more special than the 
others and not deserving of any special syntax.

To give a toy example, adding an extra attribute to the function:

def factory(argument):
    def inner():
        ...
    inner.spam = "spam"
    return inner


Another common pattern for me is changing the name of the inner 
function. Most of the time wraps() does this, but if the factory doesn't 
wrap another function, I frequently change the inner function name 
manually:

     inner.__name__ = some_name() or "default"

Admittedly even for me, the pattern of returning the function 
immediately after it is created (usually after being decorated by 
functools.wraps) is very *common*, but I don't find it *special* enough 
to justify dedicated syntax.


> Decorators don't do more than "saving one line", either.

I didn't say they did.


> But the biggest reason I'd like something like this is that it solves a
> *specific* version of the multi-line anonymous function that comes up over
> and over and over again, and maybe by chipping away at those use-cases we
> can stop seeing *that* debate over and over and over again. :-)

I don't see the connection.

"def" will still be a statement, not an expression, so you can't put it 
in expressions with or without a leading "return" statement:

    x = [spam, eggs, return def func(): block, aardvark]

nor can you put it in a lambda. So I don't see why this would help with
the anonymous code block requests.


> So, no, it doesn't save a lot of typing, but I'm never interested in that.
> I don't spend a lot of time typing code, I spend it reading code, and
> something like this would certainly help there, imho.

I don't think it will "certainly" help. I think you're projecting your own 
opinion onto others. I don't find it very readable, and neither have 
some others who commented. When I read a function def, I read it as 
short for "define", an imperative command. "return def(ine)" doesn't 
read like English to me.

I also see return, expect an expression, and instead find a statement, 
so I find it jarring.

If *everything was an expression* in Python, perhaps I would agree with 
you, but then we wouldn't need special syntax because we could already 
write "return def ...". 

But given that we do have the statement vs expression dichotomy in 
Python, making def a special case but only in return statements causes 
an exception in my brain when I read it :-)


-- 
Steve


More information about the Python-ideas mailing list