最近抽空阅读SICP,并重温《黑客帝国》这个电影给了我在计算机程序设计上有了一些灵感的启发,在正式谈论SICP之前我想先对scheme及其在程序设计语言中的地位作个简单解释,LISP是一门非常古老的语言,据说仅FORTRAN比其老迈,在经历多年落寞之后LISP突然焕发光彩,新近的流行语言不断从中吸取养分,茁壮成长,比如C#加入LAMBDA表达式,JS的闭包,垃圾回收等,为什么LISP在分支方言众多,而且没有组织统一维护的不利状况下能如此潇洒得意。现在将自己的一些理解写下笔记,方便后面温习查询。

我喜欢scheme,因为他小且纯粹,我不指望能直接用LISP做一些现实开发,只希望靠它开启我的思维,很多人之所以觉得LISP入门极难,或者SICP这本书起点太高,只是因为我们基础太差,相信如果我们之前有离散数学、数理逻辑的基础,看起来必定轻车熟路,因为相比计算机编程语言,LISP更像数学,它比C/C++更为基础和原始,就如donald e.knuth所言,计算机科学只不过是数学的一层漂亮外衣,没有离散数学、组合数学、概率论、抽象代数、基础微积分等基础数学知识,而直接阅读《计算机程序设计艺术》,不但异常艰难,而且收效甚微,所以在看这套计算机科学经典之前,最好先看看作者的另一本书《具体数学》,这是题外话,现在我证明给你看为什么lisp比C更为原始,夸张一点说:更接近真理本质。

打个不太恰当的比喻吧,你觉得1米/秒和1千克哪个大?你觉得数字1和+运算符有什么关系?你可能会说,你不是白痴吧,两个完全不同的东西,你怎能拿来类比,我想说的是,不要和"matrix"的奴隶一样,要学"neo"尽可能看透这个世界,很多人都相信真理是简单的,我也相信。几百年前没有人会觉得我们和植物有什么相同,而现在我们知道了,其实我们很像,都是由DNA/RNA传递遗传信息,都由细胞构成;几十年前没有人觉得我们和水有什么相同,现在我们知道了,其实我们都是由有限的几种元素组成。爱因斯坦发明了质能方程统一能量和质量,质量和能量其实可能只是一种事物的不同表现,不要被一切美丽的外表所迷惑,借用《黑客帝国》中的台词,何为真实?你所看到的?你所嗅到的?这些只不过是你大脑的反应。而现在的一切知识模型很可能在未来都会慢慢推翻,直到找到真理。

这里有一个可观察和可测量的概念,就如牛顿的万有引力,牛顿不知道万有引力到底是什么,他只是找到了它的作用规律,在没有找到真理之前,所有知识都只是事物的近似抽象模型,很多我们习以为常的概念却不是那么显而易见,比如:数字‘0’到底是什么,如何严格定义?你别告诉我一个圈就是个零,我也不清楚,但我知道这个问题不是那么显而易见,比如如果一个“东西”它和任何其他东西的积是它本身,它就是零,那么只要一个东西满足这个约束条件那他就是“0”,正好说明SICP第二章关于序对的阐释,不管底下如何组织序对,我只需要一个可以生成序对、两个取出前后元素的方法就行,SICP展示为了完全用过程表示数据的方式,让人大吃一惊,我们关心的是可以真正触摸产生效果的接口,一切无法观察的东西对我们来说都是没有意义的(见“看不见的龙”小故事),这个世界充满着一个规律,世界上所有物体都是透过其可以对外界产生作用的接口让外在得以察觉认识,我们知道的只是这些接口,而内部的真理却无法窥见。

可以言归正传了,看看SICP习题2.6,整个SCHEME建立在唯一一条规则上:lambda演算。发明者是著名数理逻辑学家alonzo church,已经证明了lambda演算是图灵完全的,所以一定程度上讲基于lambda演算的scheme和基于机器模型的C语言计算能力是完全等同的。C语言中数据和操作是严格区分的,静态的数据和动态的操作在我们脑海中已经根根深蒂固,但根据以上的论述,我可以想到,只要能发明一个东西,能完全满足数字的定义,那这个东西就可以完全代替数字了(本质上就是),lambda演算还真有这个能力,用操作实现数据。以下一些概念可能牵涉到数学中的实分析(推荐一本书《陶哲轩实分析》,大家可以看看如何用基本规则构成复杂的数学大厦),如果没有实分析理论基础,看数据抽象这块会有一些障碍。SICP中的例子非常简单,要大家用lambda演算建立(整数)自然数体系及自然数加法规则。
它先定义了数字0:
(define zero (lambda (f) (lambda (x) x)))

然后定义了自增1操作:
(define (add-1 n)
  (lambda (f) (lambda (x) (f ((n f) x)))))

很显然有了这两个规则,其他自然数都可以定义出来了:
1 = (add-1 zero)
2 = (add-1 (add-1 zero))
3 = (add-1 (add-1 (add-1 zero)))
...

这样表示不够直接,换成如下:
(define one (lambda (f) (lambda (x) (f x))))
(define two (lambda (f) (lambda (x) (f (f x)))))
(define three (lambda (f) (lambda (x) (f (f (f x))))))

大家看见了吧,任何自然数被都定义成过程,我们再在这些过程上定义等同的四则运算,然后提供转换到阿拉伯自然数空间的方法,就建立了属于自己的自然数体系了。这里SICP让我们定义一个基于lambda自然数定义的原生加法,很简单,a + b的加法效果只需要等同于0自增a加b次就算成功了,为了更简单的检查结果到底准确与否,先实现一个lambda自然数体系到阿拉伯自然数体系的简单方法:
(define (print-x n)
  (define (mark x)
    (display "0"))
  ((n mark) 0))

使用方法如下:
(print-x three) => 000
会打印3个'0'字符,这样我们就知道这个lambda数到底对应于自然数3了,这和原始人在还没有数字概念的情况打绳结计数是一个道理:)

加法定义如下:
(define (lmd-add a b)
 (lambda (f) (lambda (x)
  ((a f) ((b f) x)))))

测试下对不对:
(print-x (lmd-add two three))     => 00000
(print-x (add-1 (add-1 (add-1 (add-1 (add-1 zero))))))  => 00000

有兴趣的朋友还可以在这个基础上添加负数定义和加法运算。

scheme能用一条规则,推导出数字、四则运算符,甚至条件语句、循环语句等等,够原始吧,原来在C语言中被我们看来是原子的数字、运算符、流程控制关键字都可以继续分解为更细的粒度,例子中数字、加法,都只不过是lambda演算漂亮的语法糖衣(正如matrix 1中,最后neo看透了世界的外表,发现世界其实都是code)。

lisp不会衰落,只能会进化,因为他是数学家弄的一套数理逻辑,一个图灵等价的lambda演算,更直白一点讲就是用一种更简洁的方式定义了图灵机。更深层次上lisp代表了一种分析问题解决问题的思想,它和C语言所基于的数学原理从最本质上来讲是完全一样的,只是形式不同,scheme要强力依赖递归形式,其核心思想就是用简单的规则递归组合出复杂规则,将复杂现象分析抽象成简单规则的递归,这非常类似于人类大脑分析现实问题的模式(如果大家非常感兴趣可以参看一本获普利策大奖的科普书《GEB一条永恒金带》),这与类C的命令式语言强调模块治理的理念还是有很大差别的。我觉得lisp思想和分形很像,其大量用于复杂问题求解上,比如编译、定理证明等,当然问题的层次化和模块化与事物简洁规则抽象上并不冲突,相反这两种思想要在紧密配合才能将处理信息最小化,解决问题方式最优化。另外lisp给我一个明显的提醒,没有良好数学基础的程序员走不了多远(大家可以看看《编程本质》这本书,相信大家会理解这个观点)。

《量子物理史话》小故事:
“我的车库里有一条喷火的龙!”卡尔.萨根这样声称。“太稀罕了!”他的朋友连忙跑到车库中,但没有看见龙。“龙在哪里?”“哦,”萨根说,“我忘了说明,这是一条隐身的龙。”朋友有些狐疑,不过他建议,可以撒一些粉末在地上,看看龙的爪印是不是会出现。但是萨根又声称,这龙是飘在空中的。 “那既然这条龙在喷火,我们用红外线检测仪做一个热扫描?”“也不行。”萨根说,“隐形的火也没有温度。”“要么对这条龙喷漆让它现形?”--“这条龙是非物质的,滑不溜手,油漆无处可粘。”反正没有一种物理方法可以检测到这条龙的存在。萨根最后问:“这样一条看不见摸不着,没有实体的,飘在空中喷着没有热度的火的龙,一条任何仪器都无法探测的龙,和‘根本没有龙’之间又有什么差别呢?”。

转载于:https://www.cnblogs.com/effulgent/archive/2011/11/28/sicp.html

对SCHEME的一些理解(1)相关推荐

  1. wifi 最大传输速率

    一.802.11g的最大速率54Mbps的由来 802.11g工作在2.4G频段下,能够支持OFDM和CCK两种调制方式,提供16-QAM.64-QAM.BPSK和QPSK四种编码方式,我们通常说的5 ...

  2. NETGEAR拒绝连接请求_3分钟理解HTTP的请求与响应

    HTTP和HTTPS HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法. HTTPS(Hypertext Transfer ...

  3. 彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想

    OkHttp 现在统治了Android的网络请求领域,最常用的框架是:Retrofit+okhttp.OkHttp的实现原理和设计思想是必须要了解的,读懂和理解流行的框架也是程序员进阶的必经之路,代码 ...

  4. 我是如何根据豆瓣api来理解Restful API设计的

    1.什么是REST REST全称是Representational State Transfer,表述状态转移的意思.它是在Roy Fielding博士论文首次提出.REST本身没有创造新的技术.组件 ...

  5. 理解 Lua 的那些坑爹特性

    Lua 那些坑爹的特性 来源 https://blog.lilydjwg.me/2012/12/29/lua-caveats.36879.html 协程只能在 Lua 代码中使用 协程(corouti ...

  6. Android笔记一.深入理解Intent和IntentFilters(一)

    深入理解Intent和IntentFiler(一) 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)     为了比較深刻的理解并灵活使用Inten ...

  7. [翻译]深入理解Tornado——一个异步web服务器

    本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html ...

  8. Scheme 语言概要

    作为Lisp 变体,Scheme 是一门非常简洁的计算语言,使用它的编程人员可以摆脱语言本身的复杂性,把注意力集中到更重要的问题上,从而使语言真正成为解决问题的工具.本文分为上. 下两部分来介绍 sc ...

  9. (转)zookeeper理解

    分布式服务框架 Zookeeper -- 管理分布式环境中的数据 Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题 ...

  10. Hyperledger Indy 理解

    Hyperledger Indy 的优势和不足: 在 Sovrin 架构中,每个 DID 都有一个对应的专用代理程序,该程序具有自己的匿名网络地址,身份所有者可以从该地址通过加密的专用通道与另一个身份 ...

最新文章

  1. 应用中有使用到集群么?多大规模?
  2. STM32 基础系列教程 40 - Lwip_mqtt
  3. 面试系列-SpringMVC那些事(一)
  4. “天昌”的挽歌——逝去的背影(一)
  5. docker容器的基本操作
  6. django-用户文件的上传-后台上传
  7. Dataset XML 序列化,什么是序列化
  8. 企业级备份方案系列PART3:SCDPM 2012备份/恢复Exchange2010
  9. 在VS 2010中查询和导航代码
  10. localstorage本地存储
  11. 简单理解编程语言的工作原理
  12. 暑假NOIP期末考试【1】—— Phantom
  13. File类的基本操作方法
  14. java计算机毕业设计中美医院病历管理系统源代码+系统+数据库+lw文档
  15. 基于C# Winform的酒店管理系统
  16. Keras搭建神经网络BPNN(分类问题)
  17. MySQL基础回顾(七):数据查询语言DQL---select查询语句总结(篇二)
  18. 计算机网络宽带越大 网速越快,如何调节自己的电脑网速?几个步骤教你如何给电脑提速与降速!...
  19. 阿里云MQTT使用教程
  20. 用户认证与Kerberos

热门文章

  1. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_08.RequestMapping注解的作用
  2. 使用 urllib 构造请求对象
  3. [JSOI2010] 连通数
  4. ajax(form)图片上传(spring)
  5. 使用maven搭建ssm项目配置+tomact
  6. vuex的store机制1
  7. AngularJS过滤器filter-保留小数-渲染页面-小数点-$filter
  8. C语言中的循环结构与选择结构
  9. 树状数组 (数据结构)
  10. UIView用户事件响应