Last active
November 9, 2015 21:29
-
-
Save delonnewman/4f637ab23b0fa9aa12aa to your computer and use it in GitHub Desktop.
Messing around with mimicking Scheme in Ruby by implementing the Yin Yang puzzle with Kernel#callcc and a fake 'let' macro
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 |
Actually that doesn't work, I think the issue is that the call yin.(yang)
needs to be enclosed by the definitions, hence the "let" in scheme and the "lambda" in the raw Ruby version, I just created my funky "let" method to make it look more like the Scheme version.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can just use parallel assignment