日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

王垠四十行代码mark

發(fā)布時(shí)間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 王垠四十行代码mark 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近接觸到一些關(guān)于CPS編程風(fēng)格的東西,就去看了看曾今轟動(dòng)一時(shí)的王垠四十行代碼,看完有種隔行如隔山的感覺(jué)。目前只知道這些代碼能夠自動(dòng)把一個(gè)遞歸函數(shù)轉(zhuǎn)化成尾遞歸的形式,其他的就一竅不通了,只能先把代碼本身保存下來(lái)以后再研究了

;; 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

附上注釋

總結(jié)

以上是生活随笔為你收集整理的王垠四十行代码mark的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。