-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
An Iterator on big dataset (lazy generated) #4198
Comments
This should work, 99% sure it's a bug that it doesn't, but it's reasonably short. struct Int
def palindrome?
self.to_s == self.to_s.reverse
end
end
channel = Channel(Int32).new
spawn do
(100..999).each do |i|
(i..999).each do |j|
channel.send(i * j)
end
end
end
iter = Iterator.of { channel.receive? || Iterator.stop }
puts iter.select(&.palindrome?).max |
@RX14 you need to close the channel at the very end, otherwise struct Int
def palindrome?
self.to_s == self.to_s.reverse
end
end
channel = Channel(Int32).new
spawn do
(100..999).each do |i|
(i..999).each do |j|
channel.send(i * j)
end
end
channel.close
end
iter = Iterator.of { channel.receive? || Iterator.stop }
puts iter.map(&.as(Int32)).select(&.palindrome?).max
Currently: def self.of(&block : -> T)
SingletonProc(T).new(block)
end But if we change it to: module Iterator(T)
def self.of(&block : -> T)
SingletonProc(typeof(without_stop(&block))).new(block)
end
def self.without_stop(&block : -> T)
e = block.call
raise "" if e.is_a?(Iterator::Stop)
e
end
private struct SingletonProc(T)
include Iterator(T)
def initialize(@proc : -> (T | Iterator::Stop))
end
def next
@proc.call
end
end
end Then, we can get rid of the iter = Iterator.of { channel.receive? || Iterator.stop }
puts iter.select(&.palindrome?).max So we could support I'm ok with With those two things the lazy evaluation is more or less straight, yet I would personally prefer the api exposed by @bew , but sadly I see no way to get rid of the type annotation either in the channel or in a yielder helper class. |
@bcardiff I actually wrote that code on my phone while walking from memory, thanks for tidying it up and fixing the I think adding a little helper for this would be ok, with a type annotation. |
The idea of an Enumerator using fibers and channels has been around for some time. However, it has several problems:
Because it's slow we don't want to include it in the standard library and encourage its use. @bew Do you have a concrete use case for this? Right now iterators are pretty flexible, but this case is hard to express. |
I think that this can be closed in favour of #4438. |
@RX14 I agree, thanks |
From irc, someone (domgetter) asked if it was possible to do something like: (pseudo code)
Here,
nums
would be an Iterator on a big dataset, lazy generated (on demand, no space used).I implemented it this way:
I thought this would be great to gave this in the stdlib, what do you think ?
The text was updated successfully, but these errors were encountered: