Preface

everyone can design programs

everyone can experience the satisfaction that comes with creative design.

program design —but not programming— deserves the same role in a liberal-arts education as mathematics and language skills.

每个人都可以设计程序,作为一个职业程序员,更应该学习如何设计程序。

函数设计秘诀

  • 分析问题并定义数据结构
  • 声明函数需要的输入和输出的结构,搞清楚函数计算了什么并定义函数签名
  • 举例说理函数的作用
  • 把数据定义转化为函数大纲
  • 完善函数大纲,明确目的并举例
  • 测试

Prologue

介绍来基本的 lisp 语法,包括操作符和字符串

以及 DrRacket 的使用,包含 2htdp/image 对于图片的支持

定义函数

(define (FunctionName InputName) BodyExpression)

比如:

(define (y x) (* x x))

(y 1)
(y 2)
(y 3)
(y 4)
(y 5)

条件判断

(cond
[ConditionExpression1 ResultExpression1]
[ConditionExpression2 ResultExpression2]
...
[ConditionExpressionN ResultExpressionN])

比如:
 
 (define (sign x)
 (cond
 [(> x 0) 1]
 [(= x 0) 0]
 [(< x 0) -1]))

> (sign 10)
1
> (sign -5)
-1
> (sign 0)
0

下面是一个图片滚动的示例程序,有三个版本:

来分析一下这三个版本的程序,第一个版本没有任何条件限制
 第二个版本加入了条件限制,但是不太严谨(火箭最后会有一半落在窗口外部)
 第三个版本可以正常运行(火箭正好定在窗口底部)

那么,如果需求变了,现在要求程序运行在一个 200x400 的窗口中,那么你需要在程序中修改很多的地方。为了避免这种情况,可以使用 define(define Name Expression)

v4 版本的程序把窗口的宽和高,以及火箭的图片用 define 抽取了出来,这样无论是修改窗口大小还是想修改火箭的图片,都只需要修改一个地方。

What a good programmer would never live with, however, is that the program contains the same expression three times:

观察上面的 v4 版本的程序,就会发现 (- HEIGHT (/ (image-height ROCKET) 2)) 出现了三次。

这行代码做了三件事:

  1. 定义了图片的高度
  2. 把它除以2
  3. 把得到的结果用 HEIGHT 减去

我们可以抽取这个定义

(define ROCKET-CENTER-TO-TOP
(- HEIGHT (/ (image-height ROCKET) 2)))

最后我们可以得到 v5 版本的程序:

根据 v5 版本的代码,我们可以轻松的做如下修改:

  • 把窗口改成 200x400 的大小
  • 把火箭的图片改为一个 UFO
  • 让背景色总是蓝色
  • 让火箭降落在离窗口底部 10px 的地方

这个版本还剩下一个 magic numbers50 也是一个表达式,也重复出现了,所以要消除它。

另外,目前 picture-of-rocket 所接受的参数是 h (高度),其实应该是 t(时间),根据 路程 = 时间 x 速度,我们可以添加几个定义,最终的代码如下:

我们把代表 x 轴位移的 magic number 50X 来定义。
 并且定义了速度 V,和 distance,这样我们就可以非常方便的修改火箭下落的速度了。


最后要说明,编程可不是只是知道怎么调用类库来写出计算机可以理解的语言。
 真正的程序员可以系统的解决问题,并且把解决方案映射到代码上,另外还要容易让他人理解。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.