[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