java cps变换_CPS变换可以用来将普通递归转变为尾递归??

形式上能全都变成尾递归,不管你算啥,外面包上一层 k 变成尾递归了

不过尾递归不等于尾递归优化,变换前是O(啥) 。变换后还是O(啥),且更慢,因为加了一堆closure

最近领会到了 CPS 风格程序的一种妙用,或者说滥用。就是部分混杂。常见的cps风格的程序,最后返回的一般是 (k result)。但是这并不是必须的。完全可以 `(,bla ,blabla ,(k result) ,e*)

这样做的效果,就是让调用栈变混乱,强行把内部调用的一部分结果写到外面去。

也就是 我 注入 我自己

(define(simp-pred p)

(letrec

([gen

(λ (program k)

(match program

[(if(true) ,c ,a) (gen c k)]

[(if(false) ,c ,a) (gen a k)]

[(if,p ,c ,a)

(gen p (λ (pcode)

(if(equal?pcode p)

(let([cc (gen c id)]

[ac (gen a id)])

(k `(if,pcode ,cc ,ac)))

(gen `(if,pcode ,c ,a) k))))]

[(begin,e* ... ,e)

(make-begin `(,@(map(λ (x) (gen x id)) e*) ,(gen e k)))]

[,el (k el)]))])

(gen p id)))

(define(id x) x)

(simp-pred '(if(begine1 e2 (if(true)

(true)

(true)))

(begine3 e4 (if(true) e5 e6) e7)

(false)))

(begine1 e2 e3 e4 e5 e7)

;;; (make-begin expr*) flattens begin expressions in expr* and

;;; tacks the symbol begin on the front of the list, except if the

;;; list has one element, in which case it returns the element.

;;; expr* should be nonempty. E.g., (make-begin '(e1)) => e1 and

;;; (make-begin '(e1 (begin (begin e2 e3) e4) e5)) =>

;;; (begin e1 e2 e3 e4 e5).

;;;make-begin 这里可以找到 https://github.com/spiritbear/Grad-School-Code/blob/master/Assignment-3/helpers.ss

看, (simp-pred '(if (begin e1 e2 pred) c a))

能变成 (begin e1 e2 (if pred c a))

今天一不小心写出来的,自己也似懂非懂的,不保证这段没bug啊,图一乐,图一乐。

-----------------------

对于 k 的选取可以非常有创意,可以对子数据块用非常简短的K,id或者id like。然后再在最后拼起数据来。甚至不要害怕丢掉已有的k,如果有把握手头的活已经用完了,k已经发挥其使命了,完全可以在最后的contiuation里不使用 k

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值