On May 3, 2016 3:21 PM, "Michael Selik" <michael.selik@gmail.com> wrote:
>
> On Mon, May 2, 2016 at 5:36 PM Luigi Semenzato <luigi@semenzato.com> wrote:
>>
>> For context, someone ran into this problem in my team at Google (we
>> fixed it using pylint). I haven't seen any valid reason (in the bug
>> or elsewhere) in favor of these constructor semantics. From the
>> discussions I have seen, it seems just an oversight in the
>> implementation/specification of dictionary literals.  I'd be happy to
>> hear stronger reasoning in favor of the status quo.
>
>
> Do you feel that "prefer status quo" is not strong reasoning?
> http://www.curiousefficiency.org/posts/2011/02/status-quo-wins-stalemate.html
>
> Your word choice of "[no] valid reason" is interesting. In the bug tracker discussion, folks argue that the problem is easily solved with code style standards and static analyzers. I thought that was valid.

"X is detectable", whether by tools, or by magic imps yelling at you when you do it, is not an argument for X.

When asking for a useful purpose for the current semantics, "prefer the status quo" is not strong enough. "Errors should never pass silently," and there is an argument on the table that duplicate spelled-out keys are probably written in error. He isn't shifting the burden, he's putting the ball in your court.

> Literal dicts syntactically may have any expression as the key. Creating a special case for the parser to enforce uniqueness of number and string literals as keys seems more trouble than its worth.

That is an argument. Literal keys, or a single name repeated in the key list, might be an error, but you can't say the same about expressions. If you only error on literal keys, then there is an inconsistency between literals and expressions.

By the way, unless [[the name is guaranteed not to be rebound in a closure called within the dict display]], multiple items with the same variable name as key isn't necessarily an error:

    def f():
        x=1
        def g():
          nonlocal x
          x += 1
          return x
        return {x: g(), x: g(), x: g()}

    print(f())
    # {2: 2, 3: 3, 4: 4}

"Don't do that" doesn't say what the compiler behavior should be: should it analyze for nonlocal closures, or should it only check literals?