Drracket continuation

文中使用let/cc代替call/cc

Racket文档中,let/cc说明为:

(let/cc k body ...+)

Equivalent to (call/cc (lambda (k) body ...)).

首先,通过一个简单的函数来测试下continuation,注意,下面的函数执行会导致无限循环

#lang racket

(define r #f)
(define (f) (let/cc k ;开始捕获continuation,从let/cc开始直到闭括号位置
(set! r k) ;将continuation保存到变量r中
(println 1) ;continuation内部代码,与普通代码一样执行,没有区别
(r) ;调用continuation,将导致跳过之后的代码,执行continuation之后的代码即(println 3)
(println 2) ;上一句调用了continuation,因此此句被跳过,不会执行
) ;continuation捕获到此结束
(println 3) ;这是continuation之后的第一句代码,无论在何处调用continuation(r或k)时,都将从此句开始执行
(println 4)
(r) ;再次调用continuation,将导致再次从continuation结束的地方开始执行,输出3,4后又调用此句,因此导致无限循环
(println 5) ;上一句调用continuation,从continuation之后开始执行,因此这句不会执行
) ;函数结束,continuation范围也结束
(println "end") ;此句位置虽在continuation后,但是在函数f之外,因此这句也不会执行

以上代码执行时,会首先输出1,然后无限循环输出3和4,不会输出end,由此例可以看出:

continuation定义从let/cc开始,到闭括号结束,其中BODY部分与其他代码一样执行,没有特殊,调用continuation时,从continuation结束后第一行开始执行,不会

执行continuation内部的代码

continuation后续逻辑,只包含continuation所在函数,与函数外的代码无关

下面的函数,由《Teach Yourself Scheme in Fixnum Days》中13.3中的tree->generator简化而来.

#lang racket
(define p
(letrec
((caller #f)
(generate‐leaves
(lambda ()
(let/cc continuation-1
(set! generate‐leaves
(lambda ()
(continuation-1 'resume)))
(caller 21))
(let/cc continuation-2
(set! generate‐leaves
(lambda ()
(continuation-2 'resume)))
(caller 22))
(caller '())))) (lambda ()
(let/cc k
(set! caller k)
(generate‐leaves)))))
(p)
(p)

过程分析:

1、定义函数p,函数p为letrec的返回,即匿名函数

    (lambda ()
(let/cc k
(set! caller k)
(generate‐leaves)))

此时,函数尚未执行,因为caller为空,generate‐leaves为6-17行的函数

2、调用函数p,首先捕获continuation并赋值给caller,相当于注册了一个回调函数,下次调用caller时,函数从continuation之后执行

注意,函数generate‐leaves在捕获continuation的内部,因此调用caller时,不会再次调用generate‐leaves,continuation之后没有代码,因此函数p的返回值即为调用caller的参数

3、调用函数generate‐leaves,捕获当前位置的continuation,并修改函数generate‐leaves为调用当前continuation-1,然后调用caller,程序跳转到caller之后开始执行,caller之后没有代码,因此函数p返回,返回值为caller调用的参数21

4、再次调用函数p,同步骤2

5、再次调用函数generate‐leaves,此时generate‐leaves已经在步骤3中被重新绑定为调用continuation-1,因此调用generate‐leaves,将从continuation-1之后开始执行,即从12行开始执行,捕获continuation-2,重新绑定函数generate‐leaves,并返回值22

最新文章

  1. 优化curl并发使用
  2. 6.1-CALayer 使用
  3. [iOS]浅谈NSRunloop工作原理和相关应用
  4. mysql给其他用户权限访问我的数据库
  5. 发送短信(string转换为JSON)
  6. (转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例
  7. Java学习-025-类名或方法名应用之一 -- 调试源码
  8. 基于SOCK4网络协议的代理服务器端代码示例
  9. Java 中的二维数组
  10. centos 基本操作(输入法安装,adls宽带连接,查找文件,模拟终端)
  11. 对于C++中const & T operator= 的一点思考
  12. HTML5录音控件
  13. Coursera_程序设计与算法_计算导论与C语言基础_数组应用练习
  14. 32.Linux-2440下的DMA驱动(详解)
  15. Python_性能测试
  16. 开源介绍·新款简约、实用与大气的Hexo新主题:BMW
  17. CAS Client集群环境的Session问题及解决方案 不能退出登录
  18. Redis 5.0.0 releases notes
  19. VC编译错误,把类误认为是函数
  20. WPF自定义控件开发实例 - ColorPicker

热门文章

  1. 动态添加checkbox
  2. leetcode第22题:括号生成
  3. jenkins配置搭建环境
  4. Jacoco代码覆盖率工具
  5. js 实现排序算法 -- 归并排序(Merge Sort)
  6. 腾讯云服务器(centos7.2)上安装MySQL
  7. Maven基本概念和操作
  8. python 自动发送邮件遇到的问题
  9. [Golang]字符串拼接方式的性能分析
  10. windowserver 2012安装openssh