一、为什么要用Lisp语言来讨论程序设计的基础?
因为计算过程的Lisp描述(称为过程)本身又可以作为Lisp的数据来表示和操作。
这一事实的重要性在于,现存的许多威力强大的程序设计技术,都依赖于填平在
“被动的”数据和“主动的”过程之间的传统划分。
1.1程序设计的基本元素
基本表达式:用于表示语言所关心的最简单的个体。
组合的方法:通过它们可以从较简单的东西出发构造出复合的元素。
抽象的方法:通过它们可以为复合对象命名,并将它们当作单元去操作。
1.1.2 命名和环境
我们将名字标示符称为变量,它的值也就是它所对应的那个对象。
在Lisp方言Scheme里,给事物命名通过define(定义)的方式完成,输入:
(define size 2)
会导致解释器将值2与名字size相关联,size是变量。
环境:应该看到,我们可以将值与符号关联,而后又能提取出这些值,这意味着
解释器必须维护某种存储能力,以便保持有关的名字—值对偶的轨迹。这种存储被
成为环境(更精确地说,是全局环境)。
在linux的shell编程中有时也会需要设定环境变量,例如在当前路径下有脚本程序for.sh
想要直接运行该脚本程序,需要设定环境变量:PATH=$PATH:.,然后在命令行中输入
for.sh就可以直接运行该脚本程序,为什么需要设定环境变量为当前路径?因为for.sh的内容
存储在当前路径,即解释器对for.sh脚本程序的存储能力只保留在当前路径,因而需要将
环境变量设定为当前路径,才能将解释器的存储能力发挥出来。
二、Lisp语言构造过程抽象过程
Lisp语言的构造过程抽象是指将Lisp语言中的过程(procedure)作为基本的构造块,通过组合这些过程来构建更复杂的过程,从而实现对问题的解决。
Lisp中的过程是一种可执行的代码块,可以接受参数并返回结果。过程的构造过程抽象包括两个方面:
- 过程的定义:通过定义过程来抽象出一些通用的计算过程,使得这些过程可以在各种不同的上下文中使用。过程的定义使用lambda表达式,可以将过程绑定到一个符号上,从而使得在程序中可以通过该符号来调用这个过程。
- 过程的组合:通过将一些过程组合起来,可以构建出更复杂的过程,这些过程可以解决更为复杂的问题。过程的组合使用函数应用,可以将一个过程的输出作为另一个过程的输入,从而实现过程的嵌套和组合。
通过构造过程抽象,Lisp可以实现高度的模块化和抽象化,使得程序的设计和维护更加简单和灵活。同时,Lisp的构造过程抽象也为函数式编程范式的发展奠定了基础。
三、Lisp语言构造过程抽象具体例子
下面是一个具体的例子,说明如何使用Lisp语言的构造过程抽象:
假设我们要实现一个简单的图形界面应用程序,其中包含一个按钮和一个文本框。我们可以使用Lisp的构造过程抽象,将按钮和文本框抽象为对象,然后定义一些操作来操作它们。
首先,我们定义一个按钮对象,它包含一个标签和一个点击事件处理程序:
(define (make-button label callback)
(lambda (message)
(case message
((get-label) label)
((handle-click) (callback)))))
这个构造过程接受一个标签和一个回调函数作为参数,然后返回一个按钮对象。按钮对象是一个函数,它接受一个消息作为参数,并根据消息类型执行不同的操作。
例如,如果消息是“get-label”,按钮对象将返回它的标签。如果消息是“handle-click”,按钮对象将调用回调函数。
接下来,我们定义一个文本框对象,它包含一个文本和一个文本改变事件处理程序:
(define (make-textbox text callback)
(lambda (message)
(case message
((get-text) text)
((set-text) (lambda (new-text) (set! text new-text)))
((handle-change) (callback)))))
这个构造过程接受一个文本和一个回调函数作为参数,然后返回一个文本框对象。文本框对象是一个函数,它接受一个消息作为参数,并根据消息类型执行不同的操作。
例如,如果消息是“get-text”,文本框对象将返回它的文本。如果消息是“set-text”,文本框对象将设置文本为新的文本。如果消息是“handle-change”,文本框对象将调用回调函数。
最后,我们可以使用这些构造过程来创建一个图形界面应用程序:
(define button (make-button "Click me!" (lambda () (display "Button clicked!"))))
(define textbox (make-textbox "Hello, world!" (lambda () (display "Text changed!"))))
(display (button 'get-label)) ; prints "Click me!"
(button 'handle-click) ; prints "Button clicked!"
(display (textbox 'get-text)) ; prints "Hello, world!"
(textbox 'set-text "Goodbye, world!")
(display (textbox 'get-text)) ; prints "Goodbye, world!"
(textbox 'handle-change) ; prints "Text changed!"
在这个例子中,我们使用Lisp的构造过程抽象来创建一个简单的图形界面应用程序。我们定义了两个对象:按钮和文本框,然后定义了一些操作来操作它们。这让我们可以轻松地创建和操作复杂的对象,而不用担心细节。