Scheme 4 Javaer-1. 基本结构

(数据、函数、操作、表达式)

从汇编语言,我们知道了程序的最为底层的构造单元:指令和数据。(《编程导论(Java)•0.2.2 操作符和操作数》),如“MOV  AX,1234H”。

数据(data)是内存中保存的数值,Scheme的内置数据类型在后面再总结,目前使用数字型数据,如整数5,浮点数0.5和分数1/3。

在高级语言中,让计算机进行运算的各种命令被叫做操作符或操作符(operators),或更高级的命令——函数(在Java语言中称为方法、在裘大侠翻译的《计算机程序的构造和解释》中为“过程”/procedure,一般场合,我使用“函数”这个词)。

一个操作(an operation)是某些实际值和一个操作符的组合并且产生一个结果。它在各种编程语言中被编写成一个表达式。许多语言如Scheme,以表达式作为程序的基本单元。其他语言如Java,则以语句作为程序的基本单元。

操作/表达式是编程中最原始和起步级别的功能抽象。(3.1功能抽象的演化)

前缀表示法

表达式(expression)由操作符和数据组成,是对各种简单或复杂操作的描述。通常以递归的形式来定义表达式概念:(3.2.1 表达式语句)

1. 一个文字、变量是一个表达式。

2. 由操作符连接起来的表达式是一个表达式。不断地使用操作符连接,可以组成更庞大的式子。

3.特殊块 (special forms、特殊形式),不遵循表达式一般求值规则的表达式,如(define size 2)。按照阿伦佐·丘奇的拉姆达运算/演算 (λ-calculus 、lambda calculus ,lambda即希腊字母λ),所有语言要素如布尔值、数值和各种基本操作符、语句、函数定义、函数应用等都可以使用λ表达式定义,并由此形成一种编程语言。因此,所谓的特殊块,不过是λ表达式定义的一些东西在某种语言中的方便用法——语法糖。(1.4.3 函数式编程范式*)

Scheme采用前缀表示法,例如。

123

; Value: 123 (Scheme解释器看到分号,会忽略该行分号后面所有的内容。//)

(+ 1 5 )

(* 0.2  5 )

(+ 1/3  1/3)

; Value: 2/3(在REP环境中,必要时,用→取代解释器响应时打印的“; Value: ”,以表示其后为解释器的输出)

前缀表达式的缺点:它不同于数学的中缀表示法,C系的程序员会不太习惯。

前缀表达式的优点:

1.处理多个操作数。(+ 1 2 3 4) 比 1+2+3+4 要简洁;

2.更适合用于组合/嵌套场合。如(+ (* 3 (+ (* 2 4) (+ 35)))   (+ (- 10 7) 6))

 表达式的求值

参照表达式的定义,表达式的求值是一个递归处理的流程。

1. Evaluate the sub expressions of thecombination.(递归地)求组合式的子表达式的值

2. Apply the procedure that is the valueof theleft most sub expression(the operator) to the arguments that are the values ofthe other sub expressions (the operands). 将最左边的子表达式(即操作符)的值表示的过程,应用到其参数上。【过程是操作符的值

求值的递归流程可以表示成树。“值向上行走”是一种树形累积。例如

(* (+ 2 (* 4 6))

   (+ 3 5 7))

Scheme 4 Javaer-1. 基本结构_第1张图片

在叶子上,是最基本的单元:操作符(或其他名字),数。求值过程将它们的累计并向上行走/渗透。

递归是处理层次性结构(如树)的强有力技术。

注意:函数/操作符也是一种值,是最左子表达式的值。练习1.4是个好例子(if语义见<条件表达式和谓词>),代码为:

(define(a-plus-abs-b a b)

  ((if (> b 0) + -) a b))

命名和函数抽象

ava中单句分为声明语句和表达式语句。Scheme中有一些不遵循前面所述表达式的求值规则的情况,称为特殊块。有人把块(form)作为Scheme语言中的基本程序单元,一个Scheme语言程序是由一个或多个form构成。通常form 都由小括号括起来。例如

(define size 2)

它并不是将define应用到其后的表达式,其作用是将size与一个值关联起来。

Scheme 4 Javaer-1. 基本结构_第2张图片

虽然(define size 2)等类似Java中的带初始化的变量声明,但是Scheme非常谨慎地对待赋值语句。

函数抽象(函数定义)是编程语言的一个重要成分。函数是一个由一系列表达式组成的代码块,拥有一个名字(匿名函数除外)。它最重要的特点,是拥有形式参数。如求平方的函数

 (define (square x) (* x x))

将函数square作为一个操作的基本单元(building block),可以构成更复杂的函数。如求平方和的函数

(define (sum-of-squares x y)

  (+ (squarex) (square y)) )

或对于数学函数f(a)=(a+1)2+ (a*2)2的描述:

(define (f a)

 (sum-of-squares (+ a 1) (* a 2)))


条件表达式和谓词

通常,编程语言有顺序(sequencing),选择(alternation)和循环(iteration)三种控制结构,它们足以表达所有程序的本质。

对于基于函数嵌套为基本形式的函数式编程范式,顺序结构在后面说明;Scheme中通常使用递归而非迭代。这里先介绍选择结构。

数学中有许多的分段函数,如


Scheme对于这种case analysis(情况分析) ,提供了cond (which stands for``conditional'') 特殊块。它比if-else、switch更强大。绝对值函数abs定义如下:

(define (abs x)

  (cond((> x 0) x) ; 不同于switch中的相等判断

        ((= x0) 0)

       ((< x 0) (- x))))

条件结构cond后面是一系列的子句,如(<p1> <e1>)。其中p是一个布尔表达式,称为 谓词(predicate)

条件结构cond的求值过程类似Java的switch,实现计算<p1>,如果为true则 <e1>是整个表达式的值(如果 <e1>是一组表达式,则取最后的表达式的值);否则求<p2>...。如果所有谓词都是false,则cond的值无定义。所以,通常需要一个类似switch的default的子句,即else子句。

对于两路分支,Scheme也提供了if特殊块,它类似Java的?:表达式。一般形式为

(if <predicate> <consequent><alternative>)

例如

(define (abs x)

  (if (< x 0)  (- x)  x) )

相应地,有逻辑运算(and<e1> ... <en>)、(or <e1>... <en>)是特殊块,采用短路运算;

(not <e>)是一个普通的(预定义的)函数。

在此基础上,我们可以定义出更多的逻辑运算符号

(define (>= x y)  (or (> x y) (= x y)))


递归求平方根

Scheme中通常使用递归而非迭代计算。例如采用逼近法求sqrt (x),即假定猜测数y(从1猜起)是x的平方根,如果y2与x之差大于精度,则以(y+x/y)/2为新的猜测数,直到满足精度。Java代码为

    public static void sqrt(double x) {
        double guess  = 1.0;
        do{
            guess = (guess + x/guess)/2;//
        }while( Math.abs(guess*guess-x )>1E-6);
        pln("x="+x+",sqrt("+x +")="+guess);
    }
Scheme则使用递归
(define (average x y)
  (/ (+ x y) 2))
(define (improve guess x)
  (average guess (/ x guess)))
(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

(define (sqrt x)
  (sqrt-iter 1.0 x))
注:good-enough?是一个带问号的函数名。




过程的应用

求(f 5)的流程,如同将实参5替代形参,带入到函数f(a) = sum-of-squares(square(a+1)+square(a*2))中。解释器真正的工作细节,在SCIP的后面章节介绍。

顺序结构


你可能感兴趣的:(Scheme 4 Javaer-1. 基本结构)