On 18/07/18 18:43, Steve Dower wrote:
Possibly this is exactly the wrong time to propose the next big syntax
change, since we currently have nobody to declare on it, but since we're
likely to argue for a while anyway it probably can't hurt (and maybe
this will become the test PEP for whoever takes the reins?).
Many thanks for your work on this, Steve. Having just written a fair
bit of code that would have benefited from None-coalescing, I'm +1 for
"??" and "??=" and +0 for the rest.
Grammar changes
---------------
The following rules of the Python grammar are updated to read::
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' |
'^=' |
'<<=' | '>>=' | '**=' | '//=' | '??=')
power: coalesce ['**' factor]
coalesce: atom_expr ['??' factor]
atom_expr: ['await'] atom trailer*
trailer: ('(' [arglist] ')' |
'[' subscriptlist ']' |
'?[' subscriptlist ']' |
'.' NAME |
'?.' NAME)
I was a bit worried about the priority here, but your explanations
elsewhere make sense. Perhaps the PEP would benefit from being a bit
more explicit about this?
From ``calendar.py``::
encoding = options.encoding
if encoding is None:
encoding = sys.getdefaultencoding()
optdict = dict(encoding=encoding, css=options.css)
After updating to use the ``??`` operator::
optdict = dict(encoding=encoding ?? sys.getdefaultencoding(),
css=options.css)
ITYM
optdict = dict(encoding=options.encoding ?? sys.getdefaultencoding(),
css=options.css)
From ``dis.py``::
def _get_const_info(const_index, const_list):
argval = const_index
if const_list is not None:
argval = const_list[const_index]
return argval, repr(argval)
After updating to use the ``?[]`` and ``??`` operators::
def _get_const_info(const_index, const_list):
argval = const_list?[const_index] ?? const_index
return argval, repr(argval)
Here's where I start to part company. To me, the updated version is
markedly harder to read, even if it does (once deciphered) convey the
intent of the function better than the original :-) The "?." and "?[]"
operators just aren't obvious enough not to trip my internal WTF filter;
either that or I'll overlook the "?" part entirely, which is probably worse.
Just use a conditional expression
---------------------------------
Another common way to initialize default values is to use the ternary
operator.
Here is an excerpt from the popular `Requests package
<https://github.com/kennethreitz/requests/blob/14a555ac716866678bf17e43e23230d81
a8149f5/requests/models.py#L212>`_::
data = [] if data is None else data
files = [] if files is None else files
headers = {} if headers is None else headers
params = {} if params is None else params
hooks = {} if hooks is None else hooks
This particular formulation has the undesirable effect of putting the
operands
in an unintuitive order: the brain thinks, "use ``data`` if possible and
use
``[]`` as a fallback," but the code puts the fallback *before* the
preferred
value.
The author of this package could have written it like this instead::
data = data if data is not None else []
files = files if files is not None else []
headers = headers if headers is not None else {}
params = params if params is not None else {}
hooks = hooks if hooks is not None else {}
This ordering of the operands is more intuitive, but it requires 4 extra
characters (for "not "). It also highlights the repetition of identifiers:
``data if data``, ``files if files``, etc.
While the four whole extra characters bothers me not one bit, the
repetition is more of an issue. It's much worse if what you have is
more like:
item = spam.spam.spam.eggs if spam.spam.spam.eggs is not None else beans
--
Rhodri James *-* Kynesim Ltd
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/