On 13 September 2016 at 07:13, Paul Moore <p.f.mo...@gmail.com> wrote:
> If I understand the proposal, f is actually intended to be equivalent to:
>
>     def f(spam):
>         spam_val = spam()
>         if spam_val is None:
>             return None
>         eggs_val = spam_val.eggs()
>         if eggs_val is None:
>             return None
>         return eggs_val.ham
>
> Personally, I find it pretty worrying that there's this persistent
> confusion over what the proposed syntax means. Sure, it's explained in
> the PEP and proposal, but if it gets implemented it'll be in the docs.
> And yet people don't seem to read any of those - and their intuition
> of what the construct does is wrong.

Right, there are two quite reasonable interpretations for what a
conditional attribute lookup does, and the "catch and ignore
AttributeError" case is going to be more familiar to most Pythonistas,
as that's the way getattr() works when given a default value.

Consider the case of chained attribute lookup as a function using a
"None" default to getattr():

    def attr_chain_abort_on_missing(base, *attrs):
        result = base
        for attr in attrs:
            if result is None:
                break
            result = getattr(result, attr, None)
        return result

vs the actually proposed semantics:

    def attr_chain_abort_only on_none(base, *attrs):
        result = base
        for attr in attrs:
            if result is None:
                break
            result = getattr(result, attr)
        return result

In the latter version, AttibuteError escapes - it's only when the
original value is None, or an attribute exists and is None that the
iteration bails out early without raising an exception.

> IMO, the syntax may well be useful, but if we don't address the
> problem that what people *think* it means isn't what it actually
> means, then it'll do more harm than good.

Agreed, and I think a key indicator for that would be whether or not
people that saw:

    result = obj?.first?.second?.third

agreed on whether or not it could raise AttributeError or TypeError.

Any prospective PhD students in the audience looking for a language
usability question to study before 3.7b1 rolls around in 2018? :)

Cheers,
Nick.

P.S. I'll note that the *upside* I see to (this part of) the proposal
is that it would implement a *very* fine-grained "is not None" check,
where the alternative in real code would often be an overly broad
exception handling clause, like:

    try:
        result = obj.first().second.third
    except (TypeError, AttributeError):
        return None

rather then actually spelling out the fine-grained checks properly.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to