[Scheme]Understanding the Yin-Yang Puzzle
这题目确实比较杀脑细胞...
原题:
(let* ((yin
((lambda (cc) (display "@") cc) (call-with-current-continuation (lambda (c) c))))
(yang
((lambda (cc) (display "*") cc) (call-with-current-continuation (lambda (c) c)))))
(yin yang))
它会输出“@*@**@***@****@*****@******@*******@********...”
怎么理解呢?
我的方案是移除call/cc,以纯函数的方案重新表示该问题,然后应用代换模型
首先,continuation是什么?
它是一个过程,以一个值为参数,这个值对应call/cc的返回;将实参应用在continuation这个过程上,应该相当于运行程序本身
原则上,continuation中应该包含整个调用栈上各帧及运算的一系列closure,以free variable的方式链接起来,不过由于本题及其简单,大大简化了continuation的近似。
首先,yang-continuation怎么表达?
(define (make-yang-continuation yin)
(lambda (yang)
(putc #\*)
(yin yang))
)
意思是,提供yin这个free variable,就返回一个continuation;如果你以参数yang(相当于call/cc的返回)调用continuation,就相当于运行程序(即原题中let*的第二部分)
再来看yin-continuation的表示:
(define yin-continuation
(lambda (yin)
(putc #\@)
(let ((yang-continuation (make-yang-continuation yin)))
(yang-continuation yang-continuation)))
)
这个continuation不需要free variable,因此直接define;它接收一个值yin(即call/cc的返回),再以它为free variable定义yang-continuation,最后,以yang-continuation自身作为参数来继续执行(对应原题中call/cc的参数(lambda (c) c))。
最后,运行整个程序:
(yin-continuation yin-continuation)
即,yin-continuation以continuation自身作为yin的初始值,运行整个程序。
完整代码:
#lang racket (define n 0)
(define (putc c)
(cond
((< n 100) (set! n (+ n 1)) (display c))
((= n 100) (set! n (+ n 1)) (newline))
(else 'ok))
) (define (make-yang-continuation yin)
(lambda (yang)
(putc #\*)
(yin yang))
) (define yin-continuation
(lambda (yin)
(putc #\@)
(let ((yang-continuation (make-yang-continuation yin)))
(yang-continuation yang-continuation)))
) (yin-continuation yin-continuation)
这里putc打印无限输出串的前100个字符
因为只涉及纯函数,可以开始代换模型了。
下面我将yin-continuation记为y,make-yang-continuation记为m,(y x)可以代换,((m x1) x2)可以代换,前者代换的时候输出@,后者输出*:
(y y) => @ ((m y) (m y)) =>
@* (y (m y)) => @* @ ((m (m y)) (m (m y))) =>
@* @* ((m y) (m (m y))) =>
@* @** (y (m (m y))) => @* @** @ ((m (m (m y))) (m (m (m y)))) =>
@* @** @* ((m (m y)) (m (m (m y)))) =>
@* @** @** ((m y) (m (m (m y)))) =>
@* @** @*** (y (m (m (m y)))) => ...
总算找到一个能把自己糊弄过去的说法...
ps. 有人看不懂scheme,给个lua的翻译版,应该没有理解障碍了(是移除call/cc后的版本,包含了我部分解题思路)。你觉得这谜题容易懂吗:
local n =
function putc(c)
if n < then
n = n +
io.write(c)
elseif n == then
n = n +
os.exit()
end
end function make_yang_continuation(yin)
return function(yang)
putc('*')
yin(yang)
end
end
function yin_continuation(yin)
putc('@')
local yang_continuation = make_yang_continuation(yin)
yang_continuation(yang_continuation)
end yin_continuation(yin_continuation)
[Scheme]Understanding the Yin-Yang Puzzle的更多相关文章
- scheme 阴阳谜题
本篇分析continuation的一个著名例子"阴阳迷题",这是由David Madore先生提出的,原谜题如下: (let* ((yin ((lambda (foo) (disp ...
- call/cc 总结 | Scheme
call/cc 总结 | Scheme 来源 https://www.sczyh30.com/posts/Functional-Programming/call-with-current-contin ...
- 开始学习Scheme
开始学习Scheme 函数式编程(Functional Programming)是在MIT研究人工智能(Artificial Intelligence)时发明的,其编程语言为Lisp.确切地说,L ...
- [Scheme]一个Scheme的Metacircular evaluator
这个解释器可以用来跑前面两篇文章的例子,所以一并扔出来,三部曲哈哈. Lisp内置的S-expression相当于解析好的语法树,而借助quasiquote和unquote又很容易进行语法树层面的变换 ...
- 初识Continuation
本文来自网易云社区 作者:陆艺 上学时看了SICP之后就对scheme这个看上去比较古怪的语言产生了兴趣. 虽然书里并没有涉及scheme太多语法以及语言上特性的一些东西, 作为一个喜欢折腾的人, 手 ...
- Rust 阴阳谜题,及纯基于代码的分析与化简
Rust 阴阳谜题,及纯基于代码的分析与化简 雾雨魔法店专栏 https://zhuanlan.zhihu.com/marisa 来源 https://zhuanlan.zhihu.com/p/522 ...
- KDD2016,Accepted Papers
RESEARCH TRACK PAPERS - ORAL Title & Authors NetCycle: Collective Evolution Inference in Heterog ...
- CSS画图
The Shapes of CSS All of the below use only a single HTML element. Any kind of CSS goes, as long as ...
- [SQL Server] 特殊字符、上标、下标处理
今天遇到一个问题是往 SQL Server 中导入像m².m³这样的单位数据,可是在 SQL Server 中查看到的都是 m2.m3,于是在网上查了一下资料,顺便摘录下来供日后查阅. 一 Wind ...
随机推荐
- @Autowired @Resource用法
@Autowired的用法和作用 这个注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get. <bean id="u ...
- (译)如何优化cocos2d程序的内存使用和程序大小:第二部分(完)
前言:从上周发布教程的微博反应情况来看,cocos2der们对于游戏的内存问题还是非常关心的.本文是上一篇博文的续,旨在教大家如何减少cocos2d程序的大小. 全文如下: 减少你的程序的大小 把纹理 ...
- Xshell_Using X11 forwarding
FROM:http://www.netsarang.com/tutorial/xshell/1018/Using_X11_forwarding The X11 forwarding feature i ...
- 【Python自动化运维之路Day9】Socket
socket也可以认为是套接字是一种源IP地址和目的IP地址以及源端口号和目的端口号的组合.网络化的应用程序在开始任何通讯之前都必须要创建套接字.就像电话的插口一样,没有它就没办法通讯. socket ...
- SQLSERVER监控复制并使用数据库邮件功能发告警邮件
SQLSERVER监控复制并使用数据库邮件功能发告警邮件 最近熬出病来了,都说IT行业伤不起,不说了,说回今天的正题 正题 上个月月底的时候因为要搬迁机房,需要将一个数据信息数据库先搬到我们的机房,然 ...
- 学习WPF——元素绑定
概念 从源对象提取一些信息,并用这些信息设置目标对象的属性 示例 在给TextBlock控件的FontSize属性赋值时,我们使用了绑定表达式 数据绑定表达式使用XAML的标记扩展(因此具有花括号)( ...
- 最新最全的js判断移动设备及操作系统
var navigator = window.navigator, userAgent = navigator.userAgent, android = userAgent.match(/(Andro ...
- JavaScript事件详解-zepto的事件实现
zepto的event 可以结合上一篇JavaScript事件详解-原生事件基础(一)综合考虑源码暂且不表,github里还有中文网站都能下到最新版的zepto.整个event模块不长,274行,我们 ...
- atitit.web原理 理论attilax总结
atitit.web原理 理论attilax总结 1. Web3.01 2. Web的未来趋势1 3. Web语言与应用导论_百度百科.html2 4. <Web设计与编程导论(影印版)> ...
- Maven学习总结(一)——Maven入门——转载
一.Maven的基本概念 Maven(翻译为"专家","内行")是跨平台的项目管理工具.主要服务于基于Java平台的项目构建,依赖管理和项目信息管理. 1.1. ...