[Python-ideas] A "local" pseudo-function

MRAB python at mrabarnett.plus.com
Sun Apr 29 14:18:17 EDT 2018


On 2018-04-29 18:01, Tim Peters wrote:
> [Tim]
> >> ...
> >> This is the kind of code about which there have been background
> >> complaints "forever":
> >>
> >>      m1 = regexp1.match(line)
> >>      m2 = regexp2.match(iine)
> >>      if m1 and m2:
> >>          do all sorts of stuff with m1 and/or m2,
> >>          including perhaps modifying local variables
> >>          and/or global variables
> >>          and/or nonlocal variables
> >>
> >> The complaints are of two distinct kinds:
> >>
> >> 1. "I want to compute m1 and m2 _in_ the `if` test".
> >>
> >> 2. "I don't want these temp names (m1 and m2) accidentally
> >>     conflicting with local names already in scope - if these names
> >>     already exist, I want the temp names to shadow their
> >>     current bindings until the `if` structure is done".
> >>
> >> So,
> >>
> >>      if local(m1=regexp1.match(line),
> >>                m2 = regexp2.match(iine),
> >>                m1 and m2):
> >>
> >> intends to address both complaints via means embarrassingly obvious to
> >> the most casual observer ;-)
>
>
> [MRAB <python at mrabarnett.plus.com>]
> > How about these:
> >
> >     local m1, m2:
> >         m1 = regexp1.match(line)
> >         m2 = regexp2.match(line):
> >         if m1 and m2:
> >             ...
> >
> >
> >     local m1, m2:
> >
> >         if (m1 := regexp1.match(line)) and (m2 := regexp2.match(line)):
> >
> >             ...
> >
> >     local m1=regexp1.match(line), m2=regexp2.match(line):
> >         if m1 and m2:
>
>
> They address complaint #2 in what seems to me a thoroughly Pythonic
> (direct, transparent, no more magical than necessary, easy to read)
> way.  They don't address complaint #1 at all, but as you've shown (in
> the 2nd spelling)  that isn't _inherently_ tied to complaint #2
> (complaint #1 is what PEP 572 addresses).
>
> So _if_ PEP 572 is accepted, adding this form of a compound `local`
> statement too would address both of the listed complaints, at the
> "cost" of a bit more typing and adding a level of indentation.
> Neither of which bother me ;-)
>
> `local()` itself was also intended to address the
> even-more-in-the-background recurring desires for an expression (as
> opposed to statement) oriented way to use throwaway bindings; e.g.,
> instead of
>
>      temp = x + y - z + 1
>      r = temp**2 - 1/temp
>
> this instead:
>
>      r = local(t=x + y - z + 1, t**2 - 1/t)
>
> It's not an accident that the shorter `t` is used in the latter than
> the former's `temp`:  when people are wary of clobbering names by
> accident, they tend to use longer names that say "I'm just a temp -
> please don't _expect_ my binding to persist beyond the immediate uses
> on the next few lines":.
>
> Anyway, that kind of thing is common n functional languages, where
>
>      "let" pile-of-bindings "in" expression
>
> kinds of constructs are widely used _as_ (sub)expressions themselves.
>
>      local t = x + y - z + 1:
>          r = t**2 - 1/t
>
> would be the same semantically, but they'd still complain about the
> "extra" typing and the visual "heaviness" of introducing a block for
> what they _think_ of as being "just another kind of expression".
>
> The `local()` I brought up was, I think, far too biased _toward_ that
> use.  It didn't "play nice" with block-oriented uses short of
> excruciatingly deep magic.  Your `local` statement is biased in the
> other direction, but that's a Good Thing :-)
>
As well as:

     local t = x + y - z + 1: r = t**2 - 1/t

I wonder if it could be rewritten as:

     r = local t = x + y - z + 1: t**2 - 1/t

Would parentheses be needed?

     r = (local t = x + y - z + 1: t**2 - 1/t)

It kind of resembles the use of default parameters with lambda!

The names would be local to the suite if used as a statement or the 
following expression if used in an expression, either way, the bit after 
the colon.



More information about the Python-ideas mailing list