On Sat, 4 Mar 2017 at 09:46 Steven D'Aprano <st...@pearwood.info> wrote:

On Fri, Mar 03, 2017 at 10:35:18PM +0100, Michel Desmoulin wrote:

> Since the start of the discussion, contesters have been offering
> numerous solutions, all being contextual and with gotchas, none being
> obvious, simple or elegant.

I do not agree with that characterisation.


Which solution do you think is obvious, simple or elegant?


> "There should be one obvious way to do it" right?

But what is "it" here?

...


Any of the alternatives mentioned thus far solve the "too general" problem.
As far as I can see, none of them would even be a contender if list.get
existed, so I think the fact that people have spent time coming up with
them is telling.


In other words, the status quo. Be specific. Show some
code -- its okay if its simplified code, but it should be enough to
demonstrate the *use-case* for this. "I have crappy JSON" is not a
use-case. How is it crappy and how would you use list.get to fix it?


It's crappy because you have a list of things of unknown length (though I'm
inclined to disagree with the "crappy", honestly—this would seem a
perfectly reasonable thing to do if people weren't bizarrely against it). I
haven't written much Python that is not secret for a while, so excuse the
heavy paraphrasing: In my cases it is usually dealing with arguments: some
sort of list has been sent to me down the wire, let's say ["kill", "edk"].
I could write a big fancy dispatcher, but I see that as unwarranted
complexity, so I usually start with something simpler. I end up wanting to
do something like:

    target = args[1]
    reason = args.get(2, "<No reason given>")

I could equally use list.pop, which seems to be common when solving this
problem with dicts—except list.pop doesn't take a default either, for some
reason I've never quite understood.


This brings us back to the point I made really early on: this *seems*
like an obviously useful method, by analogy with dicts. I agree! It
*seems* useful, so obviously such that one of the first things I added
to my own personal toolbox of helper functions was a sequence get()
function:

def get(sequence, index, default=None):
    try:
        return sequence[index]
    except IndexError:
        return default


But then I never used it. "Seems useful" != "is useful", at least in my
experience.


Helper functions suck, in my view. I'm all for a flat function namespace
with a get() that works on anything, but that one doesn't, and "dict.get is
for dicts and get is for sequences" seems ugly.


> Plus Sven already estimated the implementation would not be very hard.

The simplicity of the implementation argues *against* the need for this
to be a built-in. If you really do need this, then why not add a
sequence get() function to your project? Its only five lines!


Why not:
- Python tries very hard to stop you from adding get() to sequences. Mixing
levels of namespacing feelss wrong, to me.
- It's another function for everybody reading your program to have to
remember about.
  - Functions have other costs too, in terms of documentation and testing.
- It's likely incompatible with other copies of the same utility.


As far as I have seen, only one person apart from myself, Kyle
Lahnakoski, has implemented this helper in their own code. And Kyle
says he has talked himself out of supporting this change.

One thing I haven't seen is anyone saying "I am constantly writing and
re-writing this same helper function over and over again! I grepped my
code base and I've recreated this helper in 30 different modules.
Maybe it should be a built-in?" That would be a good argument, but
nobody has made it. Lots of people saying that they desperately need
this method, but apparently most of them don't need it enough to write a
five line helper function to get it. They'd rather wait until they've
migrated all their code to Python 3.7.


The helper function doesn't solve the problem for me. The existing
solutions are, to my mind, ugly and non-obvious, and writing a helper that
is still ugly and non-obvious doesn't make anything better. The place to
solve this problem is in the API.


> So we have one obvious solution to a problem that:
>
> - several professional programmers said they have

I'm not convinced by claims that "I need to fetch arbitrary indexes from
sequences ALL THE TIME, sorry I can't show any examples...


It's hard to show examples because, generally speaking, when one can't do a
thing one does something else instead. I can restructure my programs to
avoid having this problem, or, if I'm in a hurry, I can use one of the many
ugly h^W^Wobvious, simple and elegant solutions, like (args[2:3] + ["<No
reason given>"])[0].

In general, I remain curious about cases in which list.get could be used
and would not be the preferred solution.

Ed
_______________________________________________
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