D
Daniel Nugent
Hello again Friends,
Welcome to another installment of Danno creates strange things that
nobody asked for and puts them on the mailing list.
Today's session is about creating sequence generators using Lazy
Evaluation of closures as opposed to the regular method involving
continuations and closures.
In terms of performance, I think it runs a smidge faster than
Generator.rb in the Standard Library, however it does snap the Stack
in half like a twig because of all of the recursive calls.
Actually, I really don't have much to say about it except I'm curious
what sorts of stuff I should add to the LazyGenerator module presented
herein to make it more useful. I think making it capable of returning
array slices would be a good start, but I'm not sure where else to
go. Would it make sense to have it support Enumerable for values
computed thus far? Or should I create a set of functions similar to
Enumerable, but all supporting the specification of a maximum depth?
class Lazy
=09instance_methods.each { |m| undef_method m unless m =3D~ /^__/ }
=09def initialize(switch =3D ne_eval, &block)
=09=09@code_block =3D block
=09=09@mode =3D switch
=09end
=09def method_missing(symbol, *args)
=09=09if @mode =3D=3D ne_eval
=09=09=09@real_obj ||=3D @code_block.call
=09=09=09@real_obj.__send__(symbol, *args)
=09=09else
=09=09=09@code_block.call().__send__(symbol, *args)
=09=09end
=09end
end
def lazy(switch =3D ne_eval, &block)
=09Lazy.new(switch, &block)
end
module LazyGenerator
=09
=09def initialize
=09=09@arr =3D []
=09=09@arr[0] =3D lazy {self.next}
=09end
=09
=09def[] n
=09=09if @arr[n].nil?
=09=09=09self[n-1].object_id
=09=09=09return @arr[n]
=09=09else
=09=09=09return @arr[n]
=09=09end
=09end
=09
=09def inspect
=09=09return "LazyGenerator"
=09end
=09
end
class PositiveInts
=09
=09include LazyGenerator
=09
=09def next(prev =3D 0, index =3D 0)
=09=09@arr[index] =3D prev+1
=09=09@arr[index+1] =3D lazy {self.next(@arr[index], index+1)}
=09=09return @arr[index]
=09end
end
class Fibs
=09include LazyGenerator
=09
=09def next(index =3D 0)
=09=09if index =3D=3D 0
=09=09=09@arr[index]=3D 0
=09=09elsif index =3D=3D 1
=09=09=09@arr[index] =3D 1
=09=09else
=09=09=09@arr[index] =3D @arr[index-1] + @arr[index-2]
=09=09end
=09=09
=09=09@arr[index+1] =3D lazy {self.next(index+1)}
=09=09return @arr[index]
=09end
end
As usual, feel free to berate me for wasting your time on
inconsequential matters.
Welcome to another installment of Danno creates strange things that
nobody asked for and puts them on the mailing list.
Today's session is about creating sequence generators using Lazy
Evaluation of closures as opposed to the regular method involving
continuations and closures.
In terms of performance, I think it runs a smidge faster than
Generator.rb in the Standard Library, however it does snap the Stack
in half like a twig because of all of the recursive calls.
Actually, I really don't have much to say about it except I'm curious
what sorts of stuff I should add to the LazyGenerator module presented
herein to make it more useful. I think making it capable of returning
array slices would be a good start, but I'm not sure where else to
go. Would it make sense to have it support Enumerable for values
computed thus far? Or should I create a set of functions similar to
Enumerable, but all supporting the specification of a maximum depth?
class Lazy
=09instance_methods.each { |m| undef_method m unless m =3D~ /^__/ }
=09def initialize(switch =3D ne_eval, &block)
=09=09@code_block =3D block
=09=09@mode =3D switch
=09end
=09def method_missing(symbol, *args)
=09=09if @mode =3D=3D ne_eval
=09=09=09@real_obj ||=3D @code_block.call
=09=09=09@real_obj.__send__(symbol, *args)
=09=09else
=09=09=09@code_block.call().__send__(symbol, *args)
=09=09end
=09end
end
def lazy(switch =3D ne_eval, &block)
=09Lazy.new(switch, &block)
end
module LazyGenerator
=09
=09def initialize
=09=09@arr =3D []
=09=09@arr[0] =3D lazy {self.next}
=09end
=09
=09def[] n
=09=09if @arr[n].nil?
=09=09=09self[n-1].object_id
=09=09=09return @arr[n]
=09=09else
=09=09=09return @arr[n]
=09=09end
=09end
=09
=09def inspect
=09=09return "LazyGenerator"
=09end
=09
end
class PositiveInts
=09
=09include LazyGenerator
=09
=09def next(prev =3D 0, index =3D 0)
=09=09@arr[index] =3D prev+1
=09=09@arr[index+1] =3D lazy {self.next(@arr[index], index+1)}
=09=09return @arr[index]
=09end
end
class Fibs
=09include LazyGenerator
=09
=09def next(index =3D 0)
=09=09if index =3D=3D 0
=09=09=09@arr[index]=3D 0
=09=09elsif index =3D=3D 1
=09=09=09@arr[index] =3D 1
=09=09else
=09=09=09@arr[index] =3D @arr[index-1] + @arr[index-2]
=09=09end
=09=09
=09=09@arr[index+1] =3D lazy {self.next(index+1)}
=09=09return @arr[index]
=09end
end
As usual, feel free to berate me for wasting your time on
inconsequential matters.