osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] Examples for PEP 572


On Wed, Jul 4, 2018 at 6:36 AM Steven D'Aprano <steve at pearwood.info> wrote:
>
> On Wed, Jul 04, 2018 at 01:03:02AM -0700, Devin Jeanpierre wrote:
>
> > The PEP doesn't talk about it, but FWIW, Go and C++17 if statements
> > allow you to put arbitrary simple statements in the suite header, and
> > by doing that, solves all the issues you and the PEP mentioned.
>
> Whether they solve "all the issues" discussed in the PEP is doubtful,
> since they're entirely limited to just if statements.

The only issue that PEP 572 has with limiting to if statements is:
"Disadvantages: Answers only a fraction of possible use-cases, even in
if/whilestatements."  The Go/C++17 syntax resolves that (while still
being limited to if statements and while statements -- the primary use
cases AFAIK, and the only ones Nathaniel agrees with).

> > In Python it'd look like this:
> >
> > if x = expr(); x < 0:
> >   do_stuff()
>
>
> That's even more doubtful, since the semicolon in Python already has a
> meaning of separating statements on a line. That could be equivalent to:
>
> if x = expr()
> x < 0:
>      do_stuff()
>
> which would clearly have to be a syntax error. *Two* syntax errors.
>
> Python's parser is restricted to LL(1) by design, so treating semicolons
> in "if" statements as a special case might not even be possible.
> But even if it is possible, not only would this special case
> break the Zen, but it would be UGLY too.

It isn't a special case, and it's still LL(1). Once you encounter an
"if", you parse n simple statements separated by a ";", until you
reach a colon. Where LL(1) runs into trouble is that last statement
must be an Expr statement, but that can be checked after parsing (e.g.
during compilation). I don't understand why you think this is
"clearly" a syntax error. (So is ":=", if you restrict yourself to the
current Python syntax.)

As for ugly... well, compare:

while (kv := x.pop())[0] is not None:
  foo(kv[1])

while k, v = x.pop(); k is not None:
  foo(v)

if (v := d[k]) == _EOF:
  return None

if v = d[k]; v == _EOF:
  return None

I like ":=" when it is the only thing in the expression: "if a:= b:"
etc.  Every other time I would prefer C++/Go's syntax.

-- Devin