-
-
Save rgaidot/bae05a48f079668e8c34 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'continuation' | |
# | |
# Messing around with mimicking Scheme in Ruby by implementing the Yin/Yang puzzle with Kernel#callcc and a fake 'let' macro | |
# | |
# See also: | |
# http://blog.gonzih.me/blog/2013/11/26/yin-yang-callcc-puzzle-in-ruby/, | |
# http://stackoverflow.com/questions/16843853/how-to-implement-let-in-scheme | |
# | |
# In Scheme (the original) | |
# | |
# (let ((yin ((lambda (cc) (display "@") cc) (call/cc (lambda (c) c)))) | |
# (yang ((lambda (cc) (display "*") cc) (call/cc (lambda (c) c))))) | |
# (yin yang)) | |
# In Ruby without a let (macro-ish method) | |
# | |
# lambda do |yin, yang| | |
# yin.call(yang) | |
# end.call(lambda { |cc| print "@"; cc }.call(callcc { |c| c }), | |
# lambda { |cc| print "*"; cc }.call(callcc { |c| c })) | |
# my let method with some funky metaprogramming | |
def let(bindings, &blk) | |
Class.new do | |
def initialize(bindings) | |
bindings.each do |name, value| | |
instance_variable_set(:"@#{name}", value) | |
self.class.send(:attr_reader, name.to_sym) | |
end | |
end | |
define_method :eval, &blk | |
end.new(bindings).eval | |
end | |
# the result is pretty comparable to the scheme version | |
let yin: -> (cc) { print "@"; cc }.(callcc { |c| c }), | |
yang: -> (cc) { print "*"; cc }.(callcc { |c| c }) do | |
yin.(yang) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment