I can write a lazy fibonacci in Clojure like this:
(def fib (lazy-cat [1 1] (map +' fib (rest fib))))
and I'm trying (unsuccessfully) to write it in Ruby like this:
fib = Enumerator.new do |yielder|
yielder << 1 << 1
fib.zip(fib.drop(1)).map do |a,b|
yielder << (a + b)
end
end
In the simplified case, this works:
fib = Enumerator.new do |yielder|
yielder << 1 << 1
puts "here"
end
puts fib.take(2).inspect
puts fib.drop(1).take(1).inspect
but this doesn't:
fib = Enumerator.new do |yielder|
yielder << 1 << 1
puts "here"
fib.drop(1)
end
puts fib.take(2).inspect
puts fib.drop(1).take(1).inspect
Why does that last example give me a SystemStackError: stack level too deep
error?
First,
fib
in the ruby version is not equivalent to the clojure version. In clojure version, it's a function.And
Enumerable#zip
,Enumerable#drop
andEnumerable.take
are not lazy unless you explicitly specify it. If you don't callEnumerable#lazy
, they return an Array (eagerly consuming all items; cause the exception).