yin-杨puzzle in Ruby
Yin-yang puzzle in Ruby
为了尝试更多地了解 call/cc
,我看到了 How does the yin-yang puzzle work? question and this explaination 阴阳谜题:
(let*
(
(yin (
(lambda (cc) (display #\@) cc)
(call/cc (lambda (c) c))
))
(yang (
(lambda (cc) (display #\*) cc)
(call/cc (lambda (c) c))
))
)
(yin yang)
)
到目前为止,我可能(或可能不)理解阴阳谜题的概念。但是我发现scheme的语法不是特别好懂,一查发现ruby有Continuation模块。由于 ruby 语法遵循程序风格,我发现 ruby 代码比方案代码更容易阅读。因此,我决定将拼图翻译成 ruby 版本(我在 scheme 和 ruby 方面都是新手):
require "continuation"
yin = (lambda do |cc|
print "@"
return cc
end).call(callcc {|c| c})
yang = (lambda do |cc|
print "*"
return cc
end).call(callcc {|c| c})
yin.call(yang)
但是这个版本打印出 @*@***********...
(demo here) 而不是 @*@**@***@****@*****@**...
,这不是我所期望的。
我的 ruby 版本正确吗?如果它不正确,那么我真的不知道从这里该做什么...
我认为你的问题 yin
和 yang
将变成 Continuation
并且它们不会一起调用,而只有 yang
嵌套在 yin
中。
yin = (lambda do |cc|
print "@"
return cc # (3) return Continuation (1)
end).call(callcc {|c| c}) # (1) this params call first
# (2) lambda will call immediately -> print the first @
# so yin = Continuation (1)
yang = (lambda do |cc|
print "*"
return cc # (6) return Continuation (4)
end).call(callcc {|c| c}) # (4) this params call first *
# (5) lambda will call immediately -> print the first *
# so yang = Continuation (4)
yin.call(yang)
现在我们可以按如下方式解释您的代码
yin = callcc {|c| c} # yin context
print '@'
yang = callcc {|cc| cc} # yang context
print '*'
yin.call(yang)
# end yang context
# end yin context
如你所见,在第一次调用(第二个@和*)后,最后一行yin.call(yang)
将继续调用yang yang ( * yang ( * yang ( ...
,如果你替换为yin.call(yin)
,输出将是 @*@*@*@*...
最后,这是我的解决方案,想法是 yin
和 yang
将嵌套在一起,下一个 yang
将包含上一个 yin
+ ' *' 和下一个 yin
将包含前一个 yang
+ '@'
require "continuation"
yin = lambda { |yang|
cc = callcc { |cc| cc }
print "@"
yang.call(cc)
}
yang = lambda { |yin|
cc = callcc { |cc| cc }
print "*"
yin.call(cc)
}
yin.call(yang)
为了尝试更多地了解 call/cc
,我看到了 How does the yin-yang puzzle work? question and this explaination 阴阳谜题:
(let*
(
(yin (
(lambda (cc) (display #\@) cc)
(call/cc (lambda (c) c))
))
(yang (
(lambda (cc) (display #\*) cc)
(call/cc (lambda (c) c))
))
)
(yin yang)
)
到目前为止,我可能(或可能不)理解阴阳谜题的概念。但是我发现scheme的语法不是特别好懂,一查发现ruby有Continuation模块。由于 ruby 语法遵循程序风格,我发现 ruby 代码比方案代码更容易阅读。因此,我决定将拼图翻译成 ruby 版本(我在 scheme 和 ruby 方面都是新手):
require "continuation"
yin = (lambda do |cc|
print "@"
return cc
end).call(callcc {|c| c})
yang = (lambda do |cc|
print "*"
return cc
end).call(callcc {|c| c})
yin.call(yang)
但是这个版本打印出 @*@***********...
(demo here) 而不是 @*@**@***@****@*****@**...
,这不是我所期望的。
我的 ruby 版本正确吗?如果它不正确,那么我真的不知道从这里该做什么...
我认为你的问题 yin
和 yang
将变成 Continuation
并且它们不会一起调用,而只有 yang
嵌套在 yin
中。
yin = (lambda do |cc|
print "@"
return cc # (3) return Continuation (1)
end).call(callcc {|c| c}) # (1) this params call first
# (2) lambda will call immediately -> print the first @
# so yin = Continuation (1)
yang = (lambda do |cc|
print "*"
return cc # (6) return Continuation (4)
end).call(callcc {|c| c}) # (4) this params call first *
# (5) lambda will call immediately -> print the first *
# so yang = Continuation (4)
yin.call(yang)
现在我们可以按如下方式解释您的代码
yin = callcc {|c| c} # yin context
print '@'
yang = callcc {|cc| cc} # yang context
print '*'
yin.call(yang)
# end yang context
# end yin context
如你所见,在第一次调用(第二个@和*)后,最后一行yin.call(yang)
将继续调用yang yang ( * yang ( * yang ( ...
,如果你替换为yin.call(yin)
,输出将是 @*@*@*@*...
最后,这是我的解决方案,想法是 yin
和 yang
将嵌套在一起,下一个 yang
将包含上一个 yin
+ ' *' 和下一个 yin
将包含前一个 yang
+ '@'
require "continuation"
yin = lambda { |yang|
cc = callcc { |cc| cc }
print "@"
yang.call(cc)
}
yang = lambda { |yin|
cc = callcc { |cc| cc }
print "*"
yin.call(cc)
}
yin.call(yang)