On Fri, 17 Jul 2020 at 12:26, <emmanuel.coir...@caissedesdepots.fr> wrote:

> Hello everyone,
>
> I'm sorry if my proposition has already being said, or even withdrawn,
> but I think that capture variables shouldn't be as implicit as they
> are now. I didn't see any mention of capture variable patterns in
> the rejected ideas. So here is my idea:
>
> I've looked at the PEP very quickly, jumping on the examples to have
> a taste and an idea of what was going here. I saw a new kind of control
> structure based on structural pattern matching (pattern based on
> classes or compositions of classes to make it short). A very good
> idea, emphasized by Tobias Kohn ("Another take on PEP 622") is that
> pattern matching eases the writting of code based on matching such
> structures, and that capturing values stored inside of these
> structures at the match time really eases the writting of the code
> associated with this match.
>
> But... looking at the examples, it wasn't very obvious that some
> variables were catching variables and some others were matching ones.
> I then read in details some rules about how to discover what is a
> captured variable. But I'm not sure everybody will do this...
>
> Zen of Python tells us that "explicit is better than implicit". I know
> this is not a rule written in the stone, but I think here, it applies
> very well.
>
> Guido said :
> > We’re really looking
> > for a solution that tells you when you’re looking at an individual
> > case which variables are captured and which are used for
> > load-and-compare.
> >
> > Marking up the capture variables with some sigil (e.g. $x or
> > x?)
> > or other markup (e.g. backticks or <x>) makes this common case ugly
> > and inconsistent: it’s unpleasant to see for example
> >
> >     case %x, %y:
> >         print(x, y)
>
> Guido talk about a "sigil", which seems to be a meaningless mark only
> here to help the parser understand what the dev was writing.
>
> I propose that this "sigil" be the affectation mark : "=". Look :
>
>     z = 42
>     match pt:
>         case x=, y=, z:
>             print(x, y, "z == 42")
>
> Or this one :
>
>     def make_point_3d(pt):
>         match pt:
>             case (x=, y=):
>                 return Point3d(x, y, 0)
>             case (x=, y=, z=):
>                 return Point3d(x, y, z)
>             case Point2d(x=, y=):
>                 return Point3d(x, y, 0)
>             case Point3d(_, _, _):
>                 return pt
>             case _:
>                 raise TypeError("not a point we support")
>
>
I kind of agree it is nicer to be more explicit.  But somehow x= looks
ugly. It occurred to me (and, again, apologies if already been mentioned),
we might use the `as` keyword here.

The example above would become:

    def make_point_3d(pt):
        match pt:
            case (as x, as y):
                return Point3d(x, y, 0)
            case (as x, as y, as z):
                return Point3d(x, y, z)
            case Point2d(as x, as y):
                return Point3d(x, y, 0)
            case Point3d(_, _, _):
                return pt
            case _:
                raise TypeError("not a point we support")

If having "as x" as a standalone expression without anything to the left of
"as" causes confusion, we could instead mandate the use of _ thus:

            case (_ as x, _ as y):
                return Point3d(x, y, 0)

On the need to be explicit:
>
> Simple case blocks will perhaps be a bit longer to write, but will
> not be harder to read, since they stay in the "simple case blocks"
> family.
>
> More complex cases will be harder to write, but the explicit markup
> will help understand what will be captured and where, and what will
> be looked-and-matched, using already known rules : looked-and-matched
> expressions will be computed as usual, then compared with the match
> term, and captured expression will be computed to a l-value (which
> is much more restrictive than random expressions).
>
> Moreover, explicilty introducing a difference between "capture" and
> "look-and-match" will help newcomers to understand what is the point
> about a match without they have to look at a PEP or other normative
> document.
>
> Remember that code has to be readable, because it will be read much
> more often than written. The reader has to understand quickly but not
> in details what will happen. Being explicit removes they the task
> to concentrate on this point.
>
> Also remember that Python has to be teached, and that all that is
> implicit in the code have to be explicited when teaching. And the
> longer you teach microdetails like what is the difference between
> "capture" vs "look-and-match", the less your audience will be prone
> to listen to you.
>
> On the drawback to be explicit:
>
> Adding a mark to every captured variables can and will be annoying.
> More annoying than not adding it. It's obvious. But we don't expect to
> have more than a handful of captured variables per case. Or the case
> is perhaps too complex, not to say perhaps too complicated.
>
> Using a carrefully choosen mark can alleviate this drawback. Using
> an already accepted and commonly used symbol will surely help.
>
> I know that Python will diverge from other languages on this point. Yes,
> but Python already diverged from others languages, and it is see
> by the community that it is for the better. Ex : the conditional expression
> aka the "ternary operator" aka "x = blabla if plop else bla".
>
> And I'll be a bit confused to have to explain that "captured variables"
> look like simple expressions "but are not" because that's how things
> are written in other functionnal languages. I'm not sure it will
> convince anybody that aren't already familiar with pattern matching in
> functionnal languages (which is a big topic by itself).
>
> On the syntax:
>
> Using the "=" character is well know, easy to find on a keyboard
> and already hold the semantics of "putting a value in a variable".
>
> So this mark is not a random sigil, but the way we write
> affectations, with a l-value, a "=" character, and a
> r-value. The r-value is given from the match and is omited here.
>
> And even if only a few ones know what "l-value" means, everybody knows
> what is allowed to put on the left side of an "=".
>
> Morever, this kind of syntax already exists in the Python world, when
> using default function parameters values :
>
>     def make_point(x=0, y=0):
>         return x, y
>
> Here the r-value is present. The l-value still has a defined
> semantic that is easy to learn and understand without requiring
> to read the Python semantics book or any PEPs. And this is still
> the same semantic of "putting a value in a variable".
>
> And see how there is "x=" in the definition, but just "x" in the body
> of the function. Like in the case block.
>
> That's why I think it will add value to be explicit about captured
> variable, and that choosing a meaningfull mark can clarify many
> implicit, and hard to understand, patterns.
>
> Emmanuel
> _______________________________________________
> 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/RDEKWUZ657BE5KSYVF7IF2N47XRQ5DEV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Gustavo J. A. M. Carneiro
Gambit Research
"The universe is always one step beyond logic." -- Frank Herbert
_______________________________________________
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/WRG4JBWMWUQM3LFWFG2J2TF3HOUYXDMH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to