PEP 718: subscriptable functions

My two three cents:

  • static typing asymmetry between functions and classes is a big pain point in general for our team (mostly data scientists). I would say, generally speaking: people love the benefits of having types, but they don’t like writing them because it’s “hard.” And a big reason it’s hard is that there are a lot of minor inconsistencies, where I have to tell people the equivalent of “oh, yeah, you can’t do it that way because of X - you need to do it like this” (which is always followed by writing 5 extra lines of something they’ve never seen before). Note: I’m not trying to convince any readers of this - if you’ve experienced it, I’m sure you’ll know what I’m talking about, but it’s beyond the scope of this discussion to walk through a bunch of concrete examples. Therefore: any concessions toward consistency (why can I do this with classes but not with functions - I thought Python had first class functions?), while they may seem minor in “functionality” benefit, are cumulatively major in making Python pleasant to use with static types.

  • giving access to this parameter at runtime seems like it would be a nice-to-have, and because I am in favor of this precisely because of the advantages of consistency, I would lean toward throwing it in. The thing that would be unpleasant is if we ended up with a situation where tools ended up requiring users to do both: e.g. my_foo = deserialize_obj[Foo](some_bytes, Foo) - i.e. passing the type as a function argument in addition to using the ‘standard’ annotation. That said, I am in favor of this also primarily as a concession toward consistency; I’ve not personally gotten to use cls.__orig_bases__ yet, so I can’t speak to the usability of the class side of things directly.

  • performance concerns of the added __getitem__ call, etc, really should not be relevant to this topic. The vast majority of real world use cases for this, I predict, will be in cases where very dynamic (and slow) code is running under the hood. The slowness from this form will be dwarfed by the slowness of whatever is actually being run. Furthermore, as has been pointed out, if there’s any need to run this inside a loop, it will be possible to construct the specialized version outside the loop and use it inside the loop.

This PEP doesn’t seem like a huge step forward, but the top two things Python static typing could use more of are:

  • consistency
  • expressivity
    and this helps with both to a small degree.