first class iterator values?

137 views
Skip to first unread message

Dan Kortschak

unread,
Aug 15, 2024, 6:09:28 PM8/15/24
to golan...@googlegroups.com
Currently the Gonum graph packages make use of go:linkname abuse to be
able to implement first class iterator values that can be passed. We
also have a reflect-based implementation, but this incurs a significant
performance cost and so cannot be used as the default implementation
(users are able to select this through build tags).

With the advent of function iterators it would (superficially) appear
that there would be a path towards making this kind of iterator value
more generally available. This currently does not work (for example
here: https://go.dev/play/p/yb-c7f_E7t3
and https://go.dev/play/p/T3lbn-XrnYd, both of which are surprising
from a the perspective of a pre-rangefunc Go user). This is not the
case with map iterators since there is no corresponding index that is
meaningful in that context, but this is a matter of runtime
implementation.

Is there any chance that something like this would be supported in the
future?

Dan

Dan Kortschak

unread,
Aug 15, 2024, 6:48:27 PM8/15/24
to golan...@googlegroups.com
On Thu, 2024-08-15 at 22:32 +0000, Costanza, Pascal wrote:
> I believe the indices in your examples are updated in the wrong
> place. The following seems to do what I believe you
> expect: https://go.dev/play/p/U2YQM3fOz98

Thanks for clearing that up; that's very useful to know. This means the
issue is only whether map iterators will ever be exposed. I'm (sadly)
guessing that this will not happen.

Dan

Costanza, Pascal

unread,
Aug 15, 2024, 7:13:37 PM8/15/24
to Dan Kortschak, 'TheDiveO' via golang-nuts
I believe the indices in your examples are updated in the wrong place. The following seems to do what I believe you expect: https://go.dev/play/p/U2YQM3fOz98

Pascal

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/d0b3bffaff27f7d3b501b1f2d327eb94e95d0829.camel%40kortschak.io.

Intel Corporation nv/sa
Froissartstraat 95
1040 Etterbeek
RPR (Brussel) 0415.497.718.
Citibank, Brussels, account BE52 5701 0312 5509

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

Costanza, Pascal

unread,
Aug 16, 2024, 3:34:55 AM8/16/24
to Dan Kortschak, golan...@googlegroups.com
I haven’t double-checked, but according to the documentation of the standard library, this should be possible: You can get an iterator over a map from the maps package, and then convert it into a pull-style iterator using the iter package.
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/75d4b45c94122309c011f60e37903ad86eb6238e.camel%40kortschak.io.

Axel Wagner

unread,
Aug 16, 2024, 5:43:55 AM8/16/24
to Costanza, Pascal, Dan Kortschak, golan...@googlegroups.com
You can also use reflect to get non-restartable map-iterators. It has some additional setup cost, but I don't think it's *a lot* and after that it should be relatively cheap.

Dan Kortschak

unread,
Aug 16, 2024, 6:05:25 AM8/16/24
to golan...@googlegroups.com
On Fri, 2024-08-16 at 07:34 +0000, Costanza, Pascal wrote:
> I haven’t double-checked, but according to the documentation of the
> standard library, this should be possible: You can get an iterator
> over a map from the maps package, and then convert it into a pull-
> style iterator using the iter package.

I think you are right. I will look into this. One thing that I'm
wondering about is where it says " It must be called when the caller is
no longer interested in next values and next has not yet signaled that
the sequence is over (with a false boolean return)." This suggests to
me that we'll be leaking something if that doesn't happen. This would
be problematic.

Axel Wagner

unread,
Aug 16, 2024, 6:10:11 AM8/16/24
to Costanza, Pascal, Dan Kortschak, golan...@googlegroups.com
Or with half the allocations: https://go.dev/play/p/LmtNdR-hfWY
I can't get it down to 1 allocation, which should be the theoretical minimum, as I can't get the compiler to move the closure and the state being closed over into one allocation.

Dan Kortschak

unread,
Aug 16, 2024, 6:19:15 AM8/16/24
to golan...@googlegroups.com
On Fri, 2024-08-16 at 12:09 +0200, 'Axel Wagner' via golang-nuts wrote:
> Or with half the allocations: https://go.dev/play/p/LmtNdR-hfWY
> I can't get it down to 1 allocation, which should be the theoretical
> minimum, as I can't get the compiler to move the closure and the
> state being closed over into one allocation.

Pascal's observation that pull iterators were what I was looking for it
really the answer here. We have a pull iterator based on reflect
already; this is easy since the reflect map iterator is already a pull
iterator. The issue was how to get language-level map iteration to be
passable as a first class iterator.

Axel Wagner

unread,
Aug 16, 2024, 7:08:43 AM8/16/24
to Dan Kortschak, golan...@googlegroups.com
Yeah. What I dislike about the Pull solution is the necessity of stopping and when to do that. And the potential runtime overhead (I'm not sure where we landed re optimizing out the extra goroutine, especially in a case like this).
But I guess you could use finalizers to solve the stopping problem for this case: https://go.dev/play/p/DQxhGSSRViJ

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages