王垠的40行代码是什么_王垠40行代码专家解读

王垠 王垠[yín],四川大学97级本科毕业,保送到清华大学计算机系直博。期间曾在清华大学计算机系软件工程专业就读,主要进行集成电路布线算法的研究。在此期间,他因《完全用gnu/linux工作》一文和对tex的推广等“非研究成果的业余东西”而出名。 在只剩一年就要博士毕业的时候,他申请退学,并将1万7千余字的“退学申请书”(题为清华梦的粉碎)公布在网上,引起舆论界一时对教育体制、理想主义等的热议。
王垠的40行代码
40行代码专家解读 1. 背景知识 cps: continuation-passing style. 有一篇介绍 cps 通俗易懂的文章(中文翻译)。
简单来讲,cps 是一种编程风格:
javascript:
(原味)
function foo(x) {
return x ;
}
(cps)
function cps_foo(x, return_point) {
return return_point (x) ;
}
cps 多了一个参数 return_point,return_point 来自 caller ,是 caller 所在的“世界”,caller 将这个“世界” 传递给 callee (cps_foo),这样 cps_foo 就无须利用额外的工具(比如堆栈)去查询 caller 的世界在哪里,以便返回,而是直接进入这个世界:return_point (x)。 这便是 cps 的初衷 —— 去掉层层嵌套的世界。行话讲就是 desugar(脱糖)。syntax sugar 是为了方便人类的表达和理解,给编程语言的核心套上的一层好吃好看的外衣,而对机器对程序的解释,需要将其还原到最本质的结构,以便机械化处理和优化,这 就是脱糖的意义。
以函数式编程的观点来看,return_point 是一个函数,以 c 观点来看,你可以把它理解为程序地址,或者,以 matrix 来看,它是 key-maker 打开门进入新世界的那把钥匙。“世界”上只有一个巨大的程序(比如,你的程序不过是在 chrome 里面运行的一个小程序,而 chrome 又是在 os 里面的一个小程序),return_point 将各种小程序窜连起来了。恩,差不多就是这个意思。只不过,在函数式程序里面(比如scheme)里面,return_point 是函数,而在过程式程序(比如c)里面它更像是 0x4f36a0c4。
这段 40 多行代码是给 scheme 程序脱糖的程序,属于解释器的代码,而不是应用代码。对其的客观评价显然只有设计解释器的人才能给出。对应用程序员的意义在于,发现每天上班时编写的代码多么无聊,此外并没有任何实用价值。
2. 运行结果 ‘x
’(lambda (x k) (k x))
‘(lambda (x k) (x 1 k))
’(f x (lambda (v0) (if v0 a b)))
‘(if x (f a (lambda (v0) v0)) b)
’(lambda (x k) (f x (lambda (v0) (if v0 (k a) (k b)))))
‘(lambda (x k) (let ((k (lambda (v0) (if v0 (k c) (k d))))) (if x (f a k) (k b))))
’(lambda (x k) (let ((k (lambda (v0) (if v0 (k c) (k d))))) (if x (k (zero? a)) (k b))))
‘(lambda (x k) (if t (if x (f a k) (k b)) (k c)))
’(lambda (x k) (let ((k (lambda (v0) (if v0 (k e) (k w))))) (if t (if x (f a k) (k b)) (k c))))
‘(lambda (x k) (let ((k (lambda (v0) (h v0 k)))) (if x (f a k) (k b))))
’(lambda (x k) (let ((k (lambda (v0) (v0 c k)))) (if x (f g k) (k h))))
‘(f a (lambda (v0) (g b (lambda (v1) (v0 v1 (lambda (v2) (f c (lambda (v3) (g d (lambda (v4) (v3 v4 (lambda (v5) (v2 v5 (lambda (v6) v6))))))))))))))
’(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))
120
原代码中最后一句 ((eval fact-cps ) 5 (lambda (v) v)) 在 racket 中要修改为:
((eval fact-cps (make-base-namespace)) 5 (lambda (v) v)) 才能通过算得 120。
3. 注释
4. 要点 ctx: 函数在执行(apply)时候的上下文环境,可理解为 c 程序中运行时的栈。
整 个 cps 的(主要)过程就是 if 分支在不断制造新的 ctx, 而 apply 分支(最后一个分支)不断在新的 ctx 中 ‘计算’ (实际上是生成 cps 函数的代码,而不是真的计算),并返回结果(到上一层 ctx)的过程。这个过程就是 scheme 的基本 eval-apply 过程。(参见sicp第四章)
这是一个解释器(解释成为 cps 风格的代码),同时也是一个cps转换器,正所谓 compiling with continuations. 另外,scheme 这种代码即数据(字符串列表)的特性,使得编写生成代码的代码相对容易和简洁。
至于代码为何有 k 这个命名。呵呵,你可以叫它 kontinuation 或者 klosure.
5. 结论 以自然语言写作比喻,编写自解释器级别的代码,就像你在写一本小说,而小说的主角也在写一本小说,这位主角在描写你,对你的刻画会影响到你,你受到影响之后又会改变小说中的主角,从而影响到他对你的描写。你俩要相安无事,情节合符逻辑地发展,直到最后圆满的结尾。这比写一本普通小说可难多了。
网友评价: 看来网友们关注的重点,都在王垠说的话上,很多网友都认为他在吹牛。但是也有网友为他说话的,觉得这40行代码,确实很厉害,有些网友还悄悄的跑去运行了一下。
网友一:这40行代码的价值,开始我是不以为然的。因为根本不懂它是干嘛用。直到自己水平的提升,又对这些代码有研究,才发现,这40行代码的价值。
网友二:这40行代码的价值既然不在于实现了cps的算法,也不在于这段代码写得有多么精简和巧妙。而是:独立思考。
网友三:这段代码的功能是自动把普通递归转换为尾递归。
网友四:不懂js的人,就算是简单的js代码也看不懂的。 很多人看不懂不代表没有人看得懂。

洛克希德马丁公司已向美国空军交付了第500架F-35A隐身战机
温湿度传感器发展现状及前景分析
不间断电源技术原理、特点及发展
疫情之下 彩电行业雪上加霜
ZU+系列MPSoC的外围接口详细分析
王垠的40行代码是什么_王垠40行代码专家解读
MODBUS RTU转EtherNet/IP网关连接希望森兰变频器案例
STM32CUBEMX开发GD32F303(12)----输出PWM及修改PWM频率与占空比
元宇宙Nb空间即将上线 打造人人都能参与的元宇宙生态
不追逐工艺的代工厂SkyWater
国产匠心之作BYCOO电动牙刷,值得拥有的良心护牙产品
无人机航测精度的影响因素与解决方案
NVIDIA面向数百万数据科学家推出全新高性能工作站
为什么莱特币网络上的采用率会高于比特币网络
郑南宁院士:人工智能带来人文风险需多学科合力解决
未来柔性触控导电膜市场将呈现出爆发式的增长
红魔5G游戏手机已开启预约该机搭载骁龙865处理器首发144Hz刷新率屏幕
人工智能迎来落地时代,风力发电运维巡检上演无人机硬核剧情
无线LED信息发布系统设计与实现
米动手环怎么样 一名合格的健康助手