王垠-40行代码 -cps.ss
;; A simple CPS transformer which does proper tail-call and does not
;; duplicate contexts for if-expressions.
;;author : Yin Wang(yw21@cs.indiana.edu)
(load "pmatch.scm")
(define cps
(lambda (exp)
(letrec
([trivial? (lambda (x) (memq x '(zero? add1 sub1)))]
[id (lambda (v) v)]
[ctx0 (lambda (v) `(k ,v))] ; tail context
[fv (let ([n -1])
(lambda ()
(set! n (+ 1 n))
(string->symbol (string-append "v" (number->string n)))))]
[cps1
(lambda (exp ctx)
(pmatch exp
[,x (guard (not (pair? x))) (ctx x)]
[(if ,test ,conseq ,alt)
(cps1 test
(lambda (t)
(cond
[(memq ctx (list ctx0 id))
`(if ,t ,(cps1 conseq ctx) ,(cps1 alt ctx))]
[else
(let ([u (fv)])
`(let ([k (lambda (,u) ,(ctx u))])
(if ,t ,(cps1 conseq ctx0) ,(cps1 alt ctx0))))])))]
[(lambda (,x) ,body)
(ctx `(lambda (,x k) ,(cps1 body ctx0)))]
[(,op ,a ,b)
(cps1 a (lambda (v1)
(cps1 b (lambda (v2)
(ctx `(,op ,v1 ,v2))))))]
[(,rator ,rand)
(cps1 rator
(lambda (r)
(cps1 rand
(lambda (d)
(cond
[(trivial? r) (ctx `(,r ,d))]
[(eq? ctx ctx0) `(,r ,d k)] ; ;tail call
[else
(let ([u (fv)])
`(,r ,d (lambda (,u) ,(ctx u))))])))))]))])
(cps1 exp id))))
;;; tests
;; var
(cps 'x)
(cps '(lambda (x) x))
(cps '(lambda (x) (x 1)))
;; no lambda (will generate identity functions to return to the toplevel)
(cps '(if (f x) a b))
(cps '(if x (f a) b))
;; if stand-alone (tail)
(cps '(lambda (x) (if (f x) a b)))
;; if inside if-test (non-tail)
(cps '(lambda (x) (if (if x (f a) b) c d)))
;; both branches are trivial, should do some more optimizations
(cps '(lambda (x) (if (if x (zero? a) b) c d)))
;; if inside if-branch (tail)
(cps '(lambda (x) (if t (if x (f a) b) c)))
;; if inside if-branch, but again inside another if-test (non-tail)
(cps '(lambda (x) (if (if t (if x (f a) b) c) e w)))
;; if as operand (non-tail)
(cps '(lambda (x) (h (if x (f a) b))))
;; if as operator (non-tail)
(cps '(lambda (x) ((if x (f g) h) c)))
;; why we need more than two names
(cps '(((f a) (g b)) ((f c) (g d))))
;; factorial
(define fact-cps
(cps
'(lambda (n)
((lambda (fact)
((fact fact) n))
(lambda (fact)
(lambda (n)
(if (zero? n)
1
(* n ((fact fact) (sub1 n))))))))))
;; print out CPSed function
(pretty-print fact-cps)
;; =>
;; '(lambda (n k)
;; ((lambda (fact k) (fact fact (lambda (v0) (v0 n k))))
;; (lambda (fact k)
;; (k
;; (lambda (n k)
;; (if (zero? n)
;; (k 1)
;; (fact
;; fact
;; (lambda (v1) (v1 (sub1 n) (lambda (v2) (k (* n v2))))))))))
;; k))
((eval fact-cps) 5 (lambda (v) v))
;; => 120
王垠-40行代码 -cps.ss的更多相关文章
- 分享一个开源的JavaScript统计图表库,40行代码实现专业统计图表
提升程序员工作效率的工具/技巧推荐系列 推荐一个功能强大的文件搜索工具SearchMyFiles 介绍一个好用的免费流程图和UML绘制软件-Diagram Designer 介绍Windows任务管理 ...
- 王垠的40行代码,究竟diao在哪里
王垠是谁? 不用我说了吧!!! 别傻谈,亮码瞧! ;; A simple CPS transformer which does proper tail-call and does not;; dupl ...
- Python人脸识别最佳教材典范,40行代码搭建人脸识别系统!
Face Id是一款高端的人脸解锁软件,官方称:"在一百万张脸中识别出你的脸."百度.谷歌.腾讯等各大企业都花费数亿来鞭策人工智能的崛起,而实际的人脸识别技术是否有那么神奇? 绿帽 ...
- jquery轮播图详解,40行代码即可简单解决。
我在两个月以前没有接触过html,css,jquery,javascript.今天我却在这里分享一篇技术贴,可能在技术大牛面前我的文章漏洞百出,也请斧正. 可以看出来,无论是div+css布局还是jq ...
- 40行代码爬取猫眼电影TOP100榜所有信息
主要内容: 一.基础爬虫框架的三大模块 二.完整代码解析及效果展示 1️⃣ 基础爬虫框架的三大模块 1.HTML下载器:利用requests模块下载HTML网页. 2.HTML解析器:利用re正则表 ...
- 女朋友汇总表格弄了大半天,我实在看不下去了,用40行代码解决问题 | Python使用openpyxl库读写表格Excel(xlsx)
1.openpyxl基本操作 python程序从excel文件中读数据基本遵循以下步骤: 1.import openpyxl 2.调用openpyxl模块下的load_workbook('你的文件名. ...
- 带大家用40行python代码实现一个疫情地图
最近两个月,因为新冠病毒无情的肆虐,相信会给每个中国人的记忆中画上重重的一笔.到今天为止,疫情形势依然十分严峻,虽然除湖北外的其他省份已经连续十一天确诊人数下降,但是接下来还有将近至少1.6亿的人口迁 ...
- 一个只有99行代码的JS流程框架
张镇圳,腾讯Web前端高级工程师,对内部系统前端建设有多年经验,喜欢钻研捣鼓各种前端组件和框架. 最近一直在想一个问题,如何能让js代码写起来更语义化和更具有可读性. 上周末的时候突发奇想,当代码在运 ...
- 王垠:完全用Linux工作
来自: Zentaur(alles klar) 录一篇旧文 作者:王垠 完全用Linux工作,抛弃windows 我已经半年没有使用 Windows 的方式工作了.Linux 高效的完成了我所有的工作 ...
随机推荐
- 深入JavaWeb技术世界15:深入浅出Mybatis基本原理
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- React-Native 之 GD (五)属性声明和属性确认 及 占位图
1.在 React-Native 创建的自定义组件是可以复用的,而开发过程中一个组件可能会由多个人同时开发或者多个人使用一个组件,为了让开发人员之间减少沟通成本,我们会对某些必要的属性进行属性声明,让 ...
- mysql 无法存储表情字符 java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xBE",...' for column 'XXXX' at row 1
1.变更字段类型 ALTER TABLE api_log MODIFY COLUMN remark longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_uni ...
- html常见兼容性问题?
1.双边距BUG float引起的 使用display 2.3像素问题 使用float引起的 使用dislpay:inline -3px 3.超链接hover 点击后失效 使用正确的书写顺序 li ...
- 009-elasticsearch5.4.3【三】搜索概述-查询模型、分页、ES数据类型
一.概述 1.查询模型 搜索API允许用户执行搜索查询并返回与查询匹配的搜索匹配.它可以跨一个或多个索引以及跨一种或多种类型执行.可以使用查询Java API提供查询.搜索请求的主体是使用Search ...
- VMware 虚拟化编程(12) — VixDiskLib Sample 程序使用
目录 目录 前文列表 vixDiskLibSample 安装 Sample 程序 Sample 程序使用方法 前文列表 VMware 虚拟化编程(1) - VMDK/VDDK/VixDiskLib/V ...
- 解决Delphi窗体缩放の疑难杂症
http://anony3721.blog.163.com/blog/static/511974201082235754423/ 解决Delphi窗体缩放の疑难杂症 2010-09-22 15:57: ...
- MYSQL的ACID
原子性 (Atomicity) 原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做. 隔离性 (Isolation) 隔离性是指多个事务并发执行的时候,事务内部的操作与其他事务 ...
- oracle--ORA常见报错
常见错误地址 http://ora-12xyz.com/error/ora-01911 ORA-01034和ORA-27101的解决办法 出现ORA-01034和ORA-27101的原因是多方面的:主 ...
- CentOS7 iptables安装及操作
添加规则时的考量点: (1)要实现哪种功能:判断添加在哪张表上: (2)报文流经的路径:判断添加在哪个链上: 链上规则的次序: (1)同类规则(访问同一应用),匹配范围小的放上面: (2)不同类规则( ...