Litmus test: Give someone who does not know Python this code example from
the PEP and ask them what it does and why it does what it does:

match get_shape():
    case Line(start := Point(x, y), end) if start == end:
        print(f"Zero length line at {x}, {y}")

I expect confusion to be the result.  If they don't blindly assume the
variables come from somewhere not shown to stop their anguish.

With Python experience, my own reading is:
 * I see start actually being assigned.
 * I see nothing giving values to end, x, or y.
 * Line and Point are things being called, probably class constructions due
to being Capitalized.
 * But where did the parameter values come from and why and how can end be
referred to in a conditional when it doesn't exist yet?
   They appear to be magic!

Did get_shape() return these? (i think not).  Something magic and *implicit
rather than explicit* happens in later lines.  The opposite of what Python
is known for.

Where's the pseudo-code describing *exactly* what the above looks like
logically speaking? (there's a TODO in the PEP for the __match__ protocol
code so I assume it will come, thanks!).  I can guess _only_ after reading
a bunch of these discussions and bits of the PEP.  Is it this?  I can't
tell.

shape = get_shape()
values_or_none = Line.__match__(shape)
if values_or_none:
  start, end = values_or_none
  if start == end:
    if x, y := Point.__match__(shape):
      print(...)
      del x, y
  else:
    print(...)
  del start, end
else:
  # ... onto the next case: ?

Someone unfamiliar with Python wouldn't even have a chance of seeing that.
I had to rewrite the above many times, I'm probably still wrong.

That sample is very confusing code.  It makes me lean -1 on the PEP overall
today.

This syntax does not lead to readable logically understandable code.  I
wouldn't encourage anyone to write code that way because it is not
understandable to others.  We must never assume others are experts in the
language they are working on code in if we want it to be maintainable.  I
wouldn't approve a code review containing that example.

It would help *in part* if ()s were not used to invoke the __match__
protocol.  I think a couple others also mentioned this earlier.  Don't make
it look like a call.  Use different tokens than ().  Point{x, y} for
example.  Or some way to use another token unused in that context in our
toolbook such as @ to signify "get a matcher for this class" instead of
"construct this class".  for example ClassName@() as our match protocol
indicator, shown here with explicit assignments for clarity:

match get_shape() as shape:
  case start, end := Line@(shape):

no implicit assignments, it is clear where everything comes from.  it is
clear it isn't a constructor call.

downside?  possibly a painful bug when someone forgets to type the @.  but
the point of it not being construction needs to be made.  not using ()s but
instead using ClassName@{} or just ClassName{} would prevent that.

The more nested things get with sub-patterns, the worse the confusion
becomes.  The nesting sounds powerful but is frankly something I'd want to
forbid anyone from using when the assignment consequences are implicit.  So
why implement sub-patterns at all?  All I see right now is pain.

-gps
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/B4OXI6CZTSNC6LHWRAKT4XVFFDIUR4K3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to