Skip to content

Instantly share code, notes, and snippets.

@rgaidot
Forked from delonnewman/yin-yang.rb
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgaidot/bae05a48f079668e8c34 to your computer and use it in GitHub Desktop.
Save rgaidot/bae05a48f079668e8c34 to your computer and use it in GitHub Desktop.
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