Ahh this is the paper where I first read about the number wheel.
I liked this paper a lot and its elegance in a functional language like haskell (maybe could be replicated with #lang lazy?).
However my naive explicit stream based implementation wasn't as pretty and used quite a bit more memory, than simpler iterative variants using some upper bound and manipulating bitvectors. (However it was more a fun afternoon experiment...)
It seemed like those iterative variants are often good in a practical setting because of caches and memory use (less memory, using contiguous arrays, resulting in less cache misses, tighter loops) which is why I also like these approaches.
I think the topic of having this algorithm be compiled down to efficient lowlevel code that doesn't use that much memory is another topic.
(Maybe racket would require me to do more of the work there in choosing other lowlevel primitives, compared to haskell which maybe does more automatic optimizations? I really don't know but if anyone knows would be interesting...)
I also wonder about using things like SIMD for the iterative approach and contrasting those with algorithms which theoretically have better complexity, but can be difficult to implement without a smart functional compiler that figures out how to use the hardware to its limit (or closer towards that). At some n the better algorithm wins, but from my limited experience it seems like sometimes the constant factors get underestimated too much. Like the better algorithm using too much memory, causing cache misses, becoming slower than the naive one, or simply having good memory layout / access patterns. Ideally functional languages would do that automatically, but it seems to me like functional languages could improve in that area, that said I just might not know about functional languages that do these lowlevel things automatically.
I guess the sham project is a step in that direction, but here I am more wondering about things the language could do automatically.