(?it=expr)
is a new atomic expression for an "it reference binding"- subsequent subexpressions (in execution order) can reference the bound subexpression using
?it
(an "it reference") ?it
is reset between statements, including before entering the suite within a compound statement (if you want a persistent binding, use a named variable)- for conditionals, put the reference binding in the conditional, as that gets executed first
- to avoid ambiguity, especially in function calls (where it could be confused with keyword argument syntax), the parentheses around reference bindings are always required
None
-aware attribute access:
value = ?it.strip()[4:].upper() if (?it=var1) is not None else None
None
-aware subscript access:
value = ?it[4:].upper() if (?it=var1) is not None else None
None
-coalescense:
value = ?it if (?it=var1) is not None else ?it if (?it=var2) is not None else var3
NaN
-coalescence:
value = ?it if not math.isnan((?it=var1)) else ?it if not math.isnan((?that=var2)) else var3
Conditional function call:
value = ?it() if (?it=calculate) is not None else default
Avoiding repeated evaluation of a comprehension filter condition:
filtered_values = [?it for x in keys if (?it=get_value(x)) is not None]
Avoiding repeated evaluation for range and slice bounds:
range((?it=calculate_start()), ?it+10)
data[(?it=calculate_start()):?it+10]
Avoiding repeated evaluation in chained comparisons:
value if (?it=lower_bound()) <= value < ?it+tolerance else 0
Avoiding repeated evaluation in an f-string:
print(f"{?it=get_value()!r} is printed in pure ASCII as {?it!a} and in Unicode as {?it}"
A possible future extension would then be to pursue PEP 3150, treating the nested namespace as an it reference binding, giving:
sorted_data = sorted(data, key=?it.sort_key) given ?it=:
def sort_key(item):
return item.attr1, item.attr2
(A potential added bonus of that spelling is that it may be possible to make "given ?it=:" the syntactic keyword introducing the suite, allowing "given" itself to continue to be used as a variable name)
(?=expr)
(binding) and?
(reference): cryptic to read, no obvious pronunciation(?expr)
(binding) and??
(reference): cryptic to read, no obvious pronunciation(that=expr)
(binding) andthat
(reference): looks too much like function call keyword arguments and ordinary variable references(?that=expr)
(binding) and?that
(reference):that
was the first pronoun considered, but the proposal switched toit
to make the boilerplate lighter
I like this a lot more than
(?=)
/?
. I get why the pure form ofthat
is problematic, but including an actual word in the grammar aids parsing by humans. The?
character still strikes me as slightly odd, because it has no analog with other Python grammar.If I may throw one more line of spelling suggestions into the pile:
{}=
and{}
. This allows for some consistency with f-strings - the{}
spelling is familiar, although the use in non-string grammar is novel.Following the f-string analog, it could be expanded to include an explicit 'that' name:
{that}=
and{that}
The grammar symbol could be literally
{that}
; or, the name provided could be used to allow multiple "that"s in a compound statement: