[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 ...
随机推荐
- tomcat提供文件下载
引用两篇博客:http://blog.csdn.net/yuan882696yan/article/details/26680253 http://www.cnblogs.com/shenliang1 ...
- Java里的构造函数(构造方法)
构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型 ...
- STL源码--iterator和traits编程技法
第一部分 iterator学习 STL iterators定义: 提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式. 任何iteartor都应该提供5 ...
- Controller将Model数据传给View层,View层应该如何处理?
首先,我们在Model层中添加一个Person类. namespace MVCTest.Models{ public class Person { public string ...
- Java多线程学习(转载)
Java多线程学习(转载) 时间:2015-03-14 13:53:14 阅读:137413 评论:4 收藏:3 [点我收藏+] 转载 :http://blog ...
- javaweb 乱码---汉字存入mysql数据库中变成乱码
今天郁闷了一天,java程序在向mysql插入数据前不是乱码,数据库安装时也选了编码为utf8(和我程序的编码格式一致).可是插入数据就变成乱码,相当郁闷. 原因:mysql的配置文件中的编码并没有改 ...
- Mac OS X上用CoreCLR运行一个真正的.NET控制台程序
这个真正的控制台程序来自corefxlab,名叫CoreClrHelloWorld,是一个跨平台的.NET控制台演示程序,可以显示微软.Linux.苹果的logo. CoreClrHelloWorld ...
- TCP与UDP协议
传输控制协议(Transmission Control Protocol, TCP)和用户数据报协议(User Datagram Protocol, UDP)是典型的传输层协议. 传输层协议基于网络层 ...
- 拒绝低调,国内首家推出微软WP8.1移动开发全套免费课程
活动类型:公开课 开始时间:2014-10-20 20:00 活动地点:YY频道:85155393 课程简介:学习本次公开课你将收获和体会到: Windwos Phone8.1的推出正是微软 ...
- [Java Web] 1、Web开发初识——一大堆历史和技术名词
LZ前言 LZ最近发现网络真是个神奇的东西,以前做的好玩的只能自娱自乐(或者说顾影自怜),现在只要发一个帖子,写一个博客,很快能引来一大群小伙伴的围观(有时候还能遇见几个大牛给个战略性的指导)...L ...