Has there been any work on using Ruby's closures to implement
call-by-need semantics, such as the freeze and thaw or delay and force
macros in Lisp?
I'm especially interested in implementations of the Streams mentioned
in Abelson amd Sussman's "Structure and Interpretation of Computer
Programs"
Thanks!
In shallow waters, shrimps make fools of dragons. - Chinese Proverb
Would it be possible to give pointers to information on the web for this
Streams idea, or perhaps give us an overview? I am intrigued as to what
they are.
Thanks
John.
At Sat, 27 Jul 2002 13:12:37 +0900,
Reginald Braithwaite-Lee wrote:
> Has there been any work on using Ruby's closures to implement
> call-by-need semantics, such as the freeze and thaw or delay and force
> macros in Lisp?
Like this?
# udelegator.rb by kjana [ruby-list:8239]
class UDelegator
def initialize(obj)
preserved = ::Kernel.instance_methods
for t in self.type.ancestors
preserved |= t.instance_methods
break if t == UDelegator
end
preserved -= ["__getobj__","to_s","nil?","to_a","hash","dup","==","=~"]
for method in obj.methods
next if preserved.include? method
undef_method method
end
end
def method_missing(msg, *arg, &block)
__getobj__.__send__(msg, *arg, &block)
end
def __getobj__
raise NotImplementError, "need to define `__getobj__'"
end
end
class Promise <UDelegator
def initialize
@proc = Proc.new
end
def __getobj__
return @obj if @obj
@obj = @proc.call
end
end
def delay(&block)
Promise.new(&block)
end
class Future <UDelegator
def initialize(&block)
@th = Thread.new(&block)
@th.abort_on_exception
end
def __getobj__
return @obj if @obj
@obj = @th.value
end
end
def future(&block)
Future.new(&block)
end
if __FILE__ == $0
class Foo
def initialize(a); @a = a; end
def [](i); @a[i]; end
def []=(i, v); @a[i] = v; end
def isa; type; end
end
puts "promise example"
foo = delay {a = Foo.new([]); for i in 1..100; print "#{i} "; a[i] = i; end; puts; a}
puts "here is `non touched' promise #{foo}"
puts "# preserved method call: promise is not evaluated here."
puts "foo.type = #{foo.type}"
puts "# unpreserved method call: promise is `touched' here."
puts "foo.isa = #{foo.isa}"
puts "foo[10] = #{foo[10]}"
puts
puts "future example"
st = 15
st = ARGV.shift.to_i if ARGV.size > 0
foo = future {sleep 10; a = Foo.new([]); for i in 1..100; print "#{i} "; a[i] = i; end; puts; a}
puts "here is `non touched' future #{foo}"
puts "# preserved method call: future is not evaluated here."
puts "foo.type = #{foo.type}"
puts "some time consuming task take place...."
sleep st;
puts "# unpreserved method call: future is `touched' here."
puts "foo.isa = #{foo.isa}"
puts "foo[10] = #{foo[10]}"
end
--
Nobu Nakada
The book is online. The chapter about streams is found at:
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5
And the complete book (great book!): is found at:
http://www-mitpress.mit.edu/sicp/
Regards
>
> Thanks
>
> John.
> And the complete book (great book!): is found at:
>
> http://www-mitpress.mit.edu/sicp/
I can only agree: I think I learnt more about programming from that single
book than from all the others...
-- Nikodemus
Wow, Thanks! Now to find the time to read it!!!!
John.
Very interesting. Thanks!!!
Since I couldn't find any, I wrote one for practice. I then got
ambitious and wrote a Denumerable module that implements potentially
infinite collections.