let[x](EXPR)
x == EXPR

let[x](a=1)
x == 1

let[x](a=1, EXPR)
x == EXPR

let[x, y](a=1, EXPR)
x == 1
y == EXPR


let[x, y](a=1, b=2, EXPR)
x == 2
y == EXPR

z = let[x, y](a=1, EXPR)
x == 1
y == EXPR
z == (1, EXPR)

Anybody seeing how the above might be useful, and address some of the concerns I've read? I don't recall seeing this suggested prior.

I like the idea behind pseudo-function let/local, especially when paired with the explanation of equal sign precedence changes within paren, but I'm having a really hard time getting over the name binding leaking out of the paren.

I like this item-ish style because it puts the name itself outside the parentheses while still retaining the benefits in readability. It also allows capturing the entire resultset, or individual parts.

On Sat, Apr 28, 2018, 6:00 PM Tim Delaney <timothy.c.delaney@gmail.com> wrote:
​​
On Sat, 28 Apr 2018 at 12:41, Tim Peters <tim.peters@gmail.com> wrote:

My big concern here involves the:

​​if local(m = re.match(regexp, line)):
    print(m.group(0))

example. The entire block needs to be implicitly local for that to work - what happens if I assign a new name in that block? Also, what happens with:

​​if local(m = re.match(regexp1, line)) or local(m = re.match(regexp2, line)):
    print(m.group(0))

Would the special-casing of local still apply to the block? Or would you need to do:

​​if local(m = re.match(regexp1, line) or re.match(regexp2, line)):
    print(m.group(0))

​This might just be lack of coffee and sleep talking, but maybe new "scoping delimiters" could be introduced. Yes - I'm suggesting introducing curly braces for blocks, but with a limited scope (pun intended).  Within a local {} block statements and expressions are evaluated exactly like they currently are, including branching statements, optional semi-colons, etc. The value returned from the block is from an explicit return, or the last evalauted expression.

a = 1
b = 2
c =
​​
local(a=3) * local(b=4)
 
​c = ​local { a=3 } * local { b=4 }

c =
​​
local(a=3
​,
 b=4
​,​
a*b)
 
​​
​c = ​
 
local
​ { 
a=3
​;​
b=4
​;​
a*b
​ }​

​c = ​
 
local
​ {
    a = 3
    b = 4
    a * b
}​

c = local(a=3,
​​
b=local(a=2, a*a), a*b)
​c = ​
 
local
​ {
    a = 3
    b = local(a=2, a*a)
    return a * b
}​
 
​​
r1, r2 = local(D = b**2 - 4*a*c,
               sqrtD = math.sqrt(D),
               twoa = 2*a,
               ((-b + sqrtD)/twoa, (-b - sqrtD)/twoa))

r1, r2 = local {
    D = b**2 - 4*a*c
    sqrtD = math.sqrt(D)
    twoa = 2*a
    return ((-b + sqrtD)/twoa, (-b - sqrtD)/twoa)
}

​​
if local(m = re.match(regexp, line)):
    print(m.group(0))

if local { m = re.match(regexp, line) }:
    print(m.group(0))

And a further implication:

a = lambda a, b: local(c=4, a*b*c)

a = lambda a, b: local {
    c = 4
    return a * b * c
}

Tim Delaney
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

On Apr 28, 2018 6:00 PM, "Tim Delaney" <timothy.c.delaney@gmail.com> wrote:
​​
On Sat, 28 Apr 2018 at 12:41, Tim Peters <tim.peters@gmail.com> wrote:

My big concern here involves the:

​​if local(m = re.match(regexp, line)):
    print(m.group(0))

example. The entire block needs to be implicitly local for that to work - what happens if I assign a new name in that block? Also, what happens with:

​​if local(m = re.match(regexp1, line)) or local(m = re.match(regexp2, line)):
    print(m.group(0))

Would the special-casing of local still apply to the block? Or would you need to do:

​​if local(m = re.match(regexp1, line) or re.match(regexp2, line)):
    print(m.group(0))

​This might just be lack of coffee and sleep talking, but maybe new "scoping delimiters" could be introduced. Yes - I'm suggesting introducing curly braces for blocks, but with a limited scope (pun intended).  Within a local {} block statements and expressions are evaluated exactly like they currently are, including branching statements, optional semi-colons, etc. The value returned from the block is from an explicit return, or the last evalauted expression.

a = 1
b = 2
c =
​​
local(a=3) * local(b=4)
 
​c = ​local { a=3 } * local { b=4 }

c =
​​
local(a=3
​,
 b=4
​,​
a*b)
 
​​
​c = ​
 
local
​ { 
a=3
​;​
b=4
​;​
a*b
​ }​

​c = ​
 
local
​ {
    a = 3
    b = 4
    a * b
}​

c = local(a=3,
​​
b=local(a=2, a*a), a*b)
​c = ​
 
local
​ {
    a = 3
    b = local(a=2, a*a)
    return a * b
}​
 
​​
r1, r2 = local(D = b**2 - 4*a*c,
               sqrtD = math.sqrt(D),
               twoa = 2*a,
               ((-b + sqrtD)/twoa, (-b - sqrtD)/twoa))

r1, r2 = local {
    D = b**2 - 4*a*c
    sqrtD = math.sqrt(D)
    twoa = 2*a
    return ((-b + sqrtD)/twoa, (-b - sqrtD)/twoa)
}

​​
if local(m = re.match(regexp, line)):
    print(m.group(0))

if local { m = re.match(regexp, line) }:
    print(m.group(0))

And a further implication:

a = lambda a, b: local(c=4, a*b*c)

a = lambda a, b: local {
    c = 4
    return a * b * c
}

Tim Delaney
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/