Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PEP 671: Add section on evaluation order #2652

Merged
merged 2 commits into from
Jun 17, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 22 additions & 39 deletions pep-0671.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,36 +72,41 @@ allows the expression to refer to other arguments.

Multiple late-bound arguments are evaluated from left to right, and can refer
to previously-defined values. Order is defined by the function, regardless of
the order in which keyword arguments may be passed. Using names of later
arguments should not be relied upon, and while this MAY work in some Python
implementations, it should be considered dubious::
the order in which keyword arguments may be passed.

def prevref(word="foo", a=>len(word), b=>a//2): # Valid
def selfref(spam=>spam): # Highly likely to give an error
def spaminate(sausage=>eggs + 1, eggs=>sausage - 1): # Confusing, may fail
def frob(n=>len(items), items=[]): # May fail, may succeed
def selfref(spam=>spam): # UnboundLocalError
def spaminate(sausage=>eggs + 1, eggs=>sausage - 1): # Confusing, don't do this
def frob(n=>len(items), items=[]): # See below

Moreover, even if syntactically and semantically legal, this kind of construct
is highly confusing to other programmers, and should be avoided.
Evaluation order is left-to-right; however, implementations MAY choose to do so
in two separate passes, first for all passed arguments and early-bound defaults,
and then a second pass for late-bound defaults. Otherwise, all arguments will be
assigned strictly left-to-right.


Choice of spelling
------------------
Rejected choices of spelling
----------------------------

While this document specifies a single syntax ``name=>expression``, alternate
spellings are similarly plausible. Open for consideration are the following::
spellings are similarly plausible. The following spellings were considered::

def bisect(a, hi=>len(a)):
def bisect(a, hi:=len(a)):
def bisect(a, hi?=len(a)):

An alternative reference implementation is under consideration, which would
use this syntax::

def bisect(a, @hi=len(a)):

Since default arguments behave largely the same whether they're early or late
bound, the syntax is deliberately similar to the existing early-bind syntax.
bound, the chosen syntax ``hi=>len(a)`` is deliberately similar to the existing
early-bind syntax.

One reason for rejection of the ``:=`` syntax is its behaviour with annotations.
Annotations go before the default, so in all syntax options, it must be
unambiguous (both to the human and the parser) whether this is an annotation,
a default, or both. The alternate syntax ``target:=expr`` runs the risk of
being misinterpreted as ``target:int=expr`` with the annotation omitted in
error, and may thus mask bugs. The chosen syntax ``target=>expr`` does not
have this problem.


How to Teach This
=================
Expand Down Expand Up @@ -137,17 +142,6 @@ be defined by the function. Additionally, dedicated sentinel objects can be
used as dictionary lookup keys, where :pep:`671` does not apply.


Interaction with annotations
============================

Annotations go before the default, so in all syntax options, it must be
unambiguous (both to the human and the parser) whether this is an annotation,
a default, or both. The alternate syntax ``target:=expr`` runs the risk of
being misinterpreted as ``target:int=expr`` with the annotation omitted in
error, and may thus mask bugs. The preferred syntax ``target=>expr`` does not
have this problem.


Implementation details
======================

Expand Down Expand Up @@ -210,14 +204,3 @@ Copyright

This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.



..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: