
On Sep 4, 2019, at 21:53, Anders Hovmöller <boxed@killingar.net> wrote:
On 4 Sep 2019, at 22:58, Andrew Barnert <abarnert@yahoo.com> wrote:
On Sep 4, 2019, at 10:17, Anders Hovmöller <boxed@killingar.net> wrote:
.
Doesn't all that imply that it'd be good if you could just pass it the queue object you want?
Pass it a queue object that you construct? Or a queue factory (which would default to the SimpleQueue class, but you could pass, e.g., partial(Queue, max_len=10)? While either of those would be more flexible, it also breaks the abstraction, and the simplicity of the API.
Well we are talking about the case where the abstraction is broken already so that seems like it's reasonable.
No it’s not. Thread pools are a perfectly good abstraction, executors are a perfectly good further abstraction on that idea, with or without blocking (as evidenced by the many APIs that do have that feature, like Ruby’s, and the many APIs that don’t, like Win32’s, all of which are usable without having to know what’s inside them, and without confusion, or even disconcerting “wtf? Oh, I get it… I guess…” moments). Being able to block on a fixed number of queued-up tasks is a useful feature. And if the only way to get it were to crack a seam in a solid abstraction, that would be a tradeoff worth discussing. But in this case, there’s a perfectly good, and obvious, API that fits the abstraction seamlessly (and that already exists in a number of APIs with the same lineage of Python’s) that gives us that feature. So why not do it that way?
It might still be worth it if anyone had a use case for anything but a fixed queue length, or a custom type of queue, etc. But I suspect nobody does.
Well if the API is changed and we just add the fixed length parameter we'd feel right stupid when the other valid use cases did show up :)
No, we’d feel appropriately conservative. :) Seriously, this is exactly why we have the YAGNI principle. We naturally always want to design the most flexible and powerful and abstract thing possible even though there’s only one simple and concrete use for it. But it’s always easy to add more flexibility later if it turns out to be needed; taking flexibility away if it turns out to be confusing or buggy or whatever usually means breaking existing code. (Don’t take that past “take that into account and think twice” into “reject all flexibility without a second thought”, or you’ll end up in extreme programming dogma land, and then you’ll be forced to write Ruby instead of Python.) This thread was started by someone who wanted blocking. I’ve had coworkers ask me how to do that, and seen dozens of questions on Stack Overflow, and implemented it myself two different ways, and I’m pretty sure lots of other real-world programs have done the same. So that’s a real need. Conversely, I don’t think I’ve ever seen anyone who wanted to use a different kind of queue for anything else, or anyone who used the more flexible in other libraries like Ruby’s to add anything but a queue bound and maybe a fail handler flag. So I’m not sure the flexibility buys us anything here.