-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iteration consuming the heap is maybe too surprising #660
Comments
Thank you for your feedback, @jedwards1211. You raise a valid point. I have never been entirely comfortable with it, as it can feel like a dark pattern. This behavior occurs because it is not straightforward to consume a binary tree in the expected order without recalculating the new top after a pop operation. Recalculating the new top is the core of the behavior when popping the top value. For this reason, the iteration process functions similarly to using At the moment, I don't have a solid solution. Some thoughts:
Typically, I don't need to maintain the binary tree structure since values are consumed and, in the event of a NACK or error, are pushed back into the tree. I believe this is the right approach. However, when it’s essential to keep the structure intact, I recommend cloning, which is why the Do you have any ideas for an efficient way to create a more intuitive behavior? |
I guess my situation is kind of unique because I just needed to send a json array of queue entries over the wire (in an RPC method for debugging the internal state of the operations). I naively assumed the default iterator would just iterate over the internal array as is, without fully sorting it. If I were designing a heap library from scratch my preference would probably be no default iterator method, and instead Another option, which would be nice from an API perspective but more tricky to implement, would be to have I can understand the goal of imitating familiar APIs from other languages though... at the time I was miffed that it clashed with JS expectations. |
As far as what might have made me more likely to notice the documented behavior when skimming, maybe a warnings section and a table of contents at the top of the readme, I could PR that |
Thank you for the great suggestion to add a warnings section and a table of contents to improve the visibility of important behaviors. I appreciate your detailed feedback. Could you submit a pull request (PR) to implement these documentation improvements? Your experience would ensure the warnings are clear and easy for other developers to find. I'm also interested in your suggestion for the optional |
@ignlg sure! I'm about to go on a trip so I could probably submit the documentation PR tomorrow but I'll have to wait until after the 8th to work on iterating in order without consuming. Feel free to bug me if I forget :) |
It's good the changelog documents this behavior, but I had mistakenly assumed iterating
Symbol.iterator
would just read out the raw backing array in unsorted order.My assumption had a significant consequence, I had a debug route for fetching the internal state of some algorithms out of my server, and I was including
[...this.heap]
in the response, and after awhile I realized that requesting this internal state was accidentally emptying the queues.Making this library have an interface familiar to users of libraries in other languages is only convenient up to the point that it goes against the conventions JS users are used to. And I think iteration not consuming underlying data is one of those conventions in JS. I'm aware of async iteration that consumes underlying data (e.g. async iterating a
ReadableStream
) but not sync iteration. I don't think the Pythonheapq
behavior should win over conventions.The text was updated successfully, but these errors were encountered: