文档章节

老赵书托(2):计算机程序的构造与解释

loda0128
 loda0128
发布于 2015/05/03 13:56
字数 2051
阅读 49
收藏 0

我要推荐的第一本书便是大名鼎鼎的《Structure and Interpretation of Computer Programs》,在国内可以买到中译版,即机械工业出版社的《计算机程序的构造与解释》。

抽象

sicp

豪不夸张地说,这是一本影响了好几代程序员的书。自从上世纪80年代MIT开始使用这本书作为教材开始,它使用Lisp语言——直到前两年才被Python取代,但是使用哪本教材不得而知,由这个侧面也可见SICP这本书的影响力有多么深远。在技术日新月异的计算机行业,有多少教材可以经得起20年的考验?

至于为什么要推荐这本书,还是要从这本书在讲什么东西谈起。您觉得,对于一个程序员来说,他最需要培养哪些能力?需要了解哪些知识?如果要我回答,我会说,一个合格的程序员需要一定要对计算机算法与数据结构有较为踏实的了解(这点在以前的文章中也重复了很多次)。至于“操作系统”、“计算机网络”、“编译原理”等课程是否重要?我不知道。这些课程都被广泛接受,所以它们肯定是有用的,但是如果您追问我它们的具体作用,我无法清晰明确地告诉您答案(例如,“编译原理”对普通程序员有什么作用?)——所以我不知道。当然,以后我还是会推荐一些这方面的书籍(因为“需要与否”其实都是个“尺度”和“方向”问题),到那时我们再继续谈论这方面的话题。

不过我可以肯定的是,一个合格的程序员(无论前台/后台,系统/应用),必须要有一定的分析问题解决问题的能力——或者说,抽象的能力。抽象是使用程序解决问题的必备手段之一。例如:

  • 您是否可以把一个多级的系统分类,理解为一颗树,然后用树或图的方式来处理它?
  • 如果让您解八皇后问题,或者走一个简单的迷宫,基本上不太会难倒你,但是您可以把自己的思路使用程序表现出来吗?
  • 领域驱动设计的一个重要部分,便是将真实世界中的“领域”提炼成模型,再使用计算机语言实现出来。

需要抽象能力的情况,数不胜数。而SICP这本书,其目标便是培养您的抽象能力,自然还有使用基本的手段进行组合来解决问题的能力。这点正如书中1.1节The Element of Programming中所述:

Thus, when we describe a language, we should pay particular attention to the means that the language provides for combining simple ideas to form more complex ideas. Every powerful language has three mechanisms for accomplishing this:

  • primitive expressions, which represent the simplest entities the language is concerned with,
  • means of combination, by which compound elements are built from simpler ones, and
  • means of abstraction, by which compound elements can be named and manipulated as units.

函数式编程

全书使用Lisp进行教学,这是一门函数式编程语言。有人说,函数式编程语言适合在实验室里把玩,不适合开发大型工程——我觉得这还是一个怎么看的问题。这里谈一个我的亲身经历:我在大学里也有课程是讲述LISP语言,但当时的感觉只是“一种比较新奇的语言”,至于它有什么用,它有什么帮助我根本一概不知。然而,经过了“工程”的磨练和实践之后,我反而慢慢体会到函数式编程的优势来。在我看来,函数式编程对于实际工程上的影响,一个主要的方面在于它可以使用更小粒度的抽象单元。对于面向对象编程来说,其抽象的最小单元为“类”和“实例”。试想如果您的程序想要展开“交互”,无论如何都必须从一个“实例”和“类”上面发起。而对于函数式编程来说,它最小粒度的抽象为“函数”。例如,您可以把一个方法作为另一个方法的参数或返回值(所谓高阶函数),而一段逻辑的实现完全可以通过“小方法”的组合来进行。不要小看这种抽象级别的改变,它会大大影响系统API的设计。

这里举一个示例。一个小问题作为示例:“求出a到b之间所有整数之和”。这很容易,您可以会这么做。

static int Sum(int a, int b)
{ int sum = 0; for (int i = a; i <= b; i++) sum += i; return sum;
}

那么,“求出a到b之间所有整数的平方之和”或“绝对值之和”呢?当然,您可以再写两个方法。但是,从函数式编程角度来说,这完全是一个可以复用的逻辑:

static int Sum(Func<int, int> f, int a, int b)
{ int sum = 0; for (int i = a; i <= b; i++) sum += f(i); return sum;
}

您可以将一个函数(在.NET里用委托表示)作为参数传入Sum方法,在调用时只需传入f的实现即可:

int i = Sum(x => x * x, 1, 3); // 14 int j = Sum(x => Math.Abs(x), -3, 3); // 12

甚至于,我们可以将其“部分应用(partial application)”1。简单说来,“部分应用”是将函数的部分参数固定,以得到一个新的函数:

static Func<int, int, int> SumCurry(Func<int, int> f)
{ return (a, b) => Sum(f, a, b);
}

这样我们就可以使用SumCurry来获得新的函数了2

var sumOfSquare = SumCurry(x => x * x); // int i = sumOfSquare(1, 3); var sumOfCube = SumCurry(x => x * x * x); // int j = sumOfCube(1, 3);

如果您理解了上面的代码,其实您已经对函数式编程更细致的抽象能力有所体会了。如果是面向对象编程,您需要怎么做呢?首先,您可能需要定义一个抽象类SumCalculator,其中有一个抽象方法为F。我们要复用算法,就必须构造SumCalculator的子类,提供F的具体实现。哪种做法简单,哪种做法繁琐,一目了然。

目前函数式编程几乎已经成了高级语言的必备特性了,如C#,F#,甚至颇有代替Java语言之势的Scala中也包含了相当的函数式编程能力。事实上,我认为出现这种趋势的一个重要原因,便在于人们之前对面向对象语言的抽象能力寄予过高期望,而这种期望的破灭(或者说“冷静”)使得许多人的注意力又回到了更容易“组合”和“复用”的函数式编程理念上。而且,其实人们从来没有放弃过对小粒度的事物的热爱。例如很多人喜欢C语言的原因,便是因为它没有庞大的架构,可以通过各种方法的组装来编写程序。而Unix编程艺术之一,便是大量小程序的组合复用。

您对函数式编程的重要性还有所怀疑吗?如果您觉得上面的例子还有些“玩具”感觉的话,您还可以参考我之前实现的CacheHelperAsyncTaskDispatcher(上下)或者微软的并行库——还有Matthew Poswysocki发起的“反对for行动”。您不妨思考一下,如果没有函数式编程特性,又该如何实现这些功能呢?

自然,函数式编程的优点远不止这一个。例如函数式编程中“无副作用”的纯函数,对于目前愈发热烈的并行环境也有重大意义。这些就要靠您来自行挖掘了3


转载自老赵的博客
http://blog.zhaojie.me/2009/07/recommended-reading-2-sicp.html#comment_lkmSMbIA07M00001有兴趣的可以多关注关注这位大牛的博客

本文转载自:http://blog.zhaojie.me/2009/07/recommended-reading-2-sicp.html#comment_lkmSMbIA07M00001

上一篇: 外观模式
下一篇: 责任链模式
loda0128
粉丝 93
博文 96
码字总数 119400
作品 0
朝阳
程序员
私信 提问
分享一些书籍,方方面面,很多值得一读

分享一些书籍,方方面面,很多值得一读 编程书很多,各式各样的, 有的书讲实战,有的书讲内功, 主要分享一些自己收集且提升编程内功的书籍。 先介绍老本行的书 初级入门 JavaScript圣经之一...

街角盒饭
2017/04/01
0
0
盗梦空间科普札记之一:梦里乾坤嵌套深,醒来可知在哪层?

盗梦空间科普札记之一:梦里乾坤嵌套深,醒来可知在哪层? (唐常杰) (这是发在科学博客上一个系列博文的1/4,涉及到递归算法,第四篇涉及到图灵机停机问题,稍难一些) 上周五晚上,和几位中...

tangchangjie
2013/06/27
0
0
每个程序员都该阅读的书

本文由从What is the single most influential book every programmer should read?翻译而来。 国外知名网站stackoverflow上有一个问题调查: 哪本书是对程序员最有 影响、每个程序员都该阅读...

红薯
2011/05/01
11K
23
对程序员最具影响的,每个程序员都应该阅读的书籍

国外知名网站 stackoverflow 上有一个问题调查: 哪本书是对程序员最有影响、每个程序员都该阅读的书?, 这个调查已历时两年,目前为止吸引了 153,432 人访问,读者共推荐出了 478 本书(还在...

zhangkaixuan
2011/03/19
967
4
哪本书是每个程序员都该阅读的?

本文是从 What is the single most influential book every programmer should read? 这篇文章翻译而来。 国外知名网站stackoverflow上有一个问题调查: 哪本书是对程序员最有影响、每个程序...

红薯
2011/03/07
3.6K
25

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
1K
13
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
38
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部