[Python-ideas] Syntax: 'return: ...' expressions

Yawar Amin yawar.amin at gmail.com
Mon Jan 5 04:47:06 CET 2015


Note: I'm reposting this here after posting on the /r/Python reddit as
I've realised this is a better venue:
http://www.reddit.com/r/Python/comments/2ra8yc/return_expressions/

I have an idea for a new syntax element that combines any number of
statements and expressions into a single expression. I'm partial to
calling it a 'return' expression because that should be compatible with
existing code--there's guaranteed to be no existing code of the form
'return:'. But we could call it 'do' or 'val' or 'expr' or whatever.

    expression ::= ... | return_expr
    return_expr ::= "return" ":" statement* expression+

We can define all expression-oriented syntax in terms of return
expressions. I.e., wrap up all statement-oriented syntax inside an
expression. E.g.,

    x = (
      return:
        if y == 1: z = 'a'
        elif y == 2: z = 'b'
        elif y == 3: z = 'c'
        else: z = 'd'
        z
    )

Or a single-line example,

    x = return: print "Blah"; 5

I know, it's the Python programmer's dreaded multi-line expression. Note
here that I'm not proposing any change to indentation rules. I'm relying
on parens to relax the rules. There's precedent for using parens in new
kinds of expressions--e.g. generator expressions. So the usage shouldn't
look alien in Python code.

Now the controversy. We can use a return expression to get a multi-line,
multi-statement, lambda, as long as lambda only cares that its body is
a single exprssion. Which I believe is the case, e.g. this is valid
Python today:

    f = lambda x: (
      x,
      x + 1,
      x + 2
    )

Anyway, an imaginary lambda example:

    txtName.text.signal.map(
      # Need to wrap the return expr in parens to separate the lambdas.
      lambda s: (
        return:
          l = len(s)
          l >= 5
      ),

      # The next argument, a lambda without a return expr, happily lives
      # alongside.
      lambda err: notifications.send(err)
    ).subscribe(
      # Parens not needed here, only a single argument.
      lambda flag:
        return:
          pnlMain.back_color = "green" if flag else "red"

          # Must end with an expr, unlike a normal function. Think of it
          # this way: we're 'inside' a return, we _have to_ return
          # some value.
          None
    )

I believe 'return: ...' is an unintrusive and versatile solution. It's
_not_ meant to just forcefully shoehorn full functionality into lambdas
as I believe I show above; it doesn't break compatibility; it doesn't
require any indent/whitespace rule changes; and it's guaranteed to not
affect _any_ existing code.

Regards,

Yawar

P.S. Relevant:

https://groups.google.com/d/msg/python-ideas/kYQbvsmyM-4/ufU26RPTjLQJ

  'A much better idea would be to find a way to make all compound
  statements into expressions, future-proofing the decision and avoiding
  the redundancy between "compound statement statement" and "compound
  statement expression".'

https://groups.google.com/d/msg/python-ideas/EQQq3--DDu0/UTcfI34sVwwJ

  'Something that has started to annoy me in the last couple of years is
  the fact that most Python control statements cannot be used as
  expressions.  I feel this is a pretty deep limitation and personally I
  don't feel it's well-justified.'


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 834 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150104/6dccc00f/attachment-0001.sig>


More information about the Python-ideas mailing list