最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界快消息!Lisp的求值规则

来源:博客园

Lisp的求值规则

有些例子以scheme为例,不过大多在lisp都是通用的

lisp几乎所有类型都可以被求值。


(相关资料图)

数据类型的值:

  • 数的值就是它本身(它抽象概念上代表的那个数)。

  • 字符串也对自身求值。

  • 符号|-如果被引用(quote)的话,就表示它本身。

    |-如果不被引用,就是 关联着这个符号的对象

    • 如:函数 它的值是一个过程,一个对参数进行相关运算的过程,或者具体点说,就像是数学上的函数的表达式,如f(x,y)=x^2+y^2等。

    |-内部操作符(如+,-)就是相关的一系列机器代码。

  • 列表|-被引用,就是一个列表。

    |-不被引用,就是函数调用,它的值就是那个表达式的值。

一般的求值规则

为了方便,咱们称 由多个小表达式组成的叫组合式,小表达式叫子表达式。

一)对基础的函数调用求值(以(+ 2 3)为例):

  1. 首先从左至右对实参求值。&在本例中,数对自身求值,所以实参的值分别是23
  2. 实参的值传入以操作符命名的函数。&本例中,将23传给+函数,返回5

二)对组合式求值 与上类似(跳过_):

  1. 求值该组合式的各个子表达式。
  2. 将最左边的子表达式(运算符)的值(通常是过程)应用于相应的实际参数(其他子表达式的值)。

说白就是,先表达式的各个成分自己求值,然后因为最左边的函数的值是过程需要实参,所以将表达式的实参的值传入函数,最后函数的值作为表达式的值。

一些特殊的求值规则

lisp的大多数用到的都是一般求值规则,但有时候也需要特殊的求值规则

quote

这个大家都知道,就是 引用,简写 "英文单引号,它的求值规则就是什么也不做,接受一个实参,直接返回被引用的部分。如:

> "(+ 1 2)(+ 1 2)

条件

像cond,if

定义

像define...

正则序和应用序

其实我们上述所说的一般求值规则,它的求值顺序被称为应用序与之对应的是正则序

  • 应用序就是先对参数求值,而后应用于函数。
  • 正则序是先用将表达式完全展开,直到只包含基本运算符,然后在去求值。

就比如,我们定义一个函数,通过余弦定理来计算cosA的值。

; 以scheme为例; a b c是三角形的三边> (define (cosA a b c)    (/ (- (+ (square b)             (square c))          (square a))       (* 2 b c)))

例如(cosA (+ 1 2) 4 3)

#|应用序    就是(+ 1 2) 4 3先求值,然后代入cosA表达式,    然后再求子表达式square的值。。。    重复上述过程,最后求值。    正则序    (cosA (+ 1 2) 4 3)    1.    (/ (- (+ (square 4)             (square 3))          (square (+ 1 2))       (* 2 4 3)))    2.    (/ (- (+ (* 4 4)             (* 3 3))          (* (+ 1 2) (+ 1 2))   <-这里,就比应用的多用个加法函数       (* 2 4 3)))    3.    然后就是计算。。|#

可能我这个例子不是很直观,但我们都能知道 当复杂了的时候,我们要进行多次的外部函数调用,那样就重复运行了很多。

应用序可以节省一些资源,这俩一般影响的只是过程、复杂度(空间时间),一般不影响结果。

我们解释器大多时候采用应用序进行求值,不过一些特殊语句是用正则序的。如if语句。

xxxx

补充

或许通过求 阶乘 来比较两个会很明显。

> (define (factorial n)    (if (= 1 n)        n        (* n (factorial (- n 1)))))

例如:

> (factorial 10)3628800

如果 if 是应用序

(factorial 10)(if (= 10 1) 1 (* 10 (factorial 9)))(if (= 10 1) 1 (* 10 (if (= 9 1) 1 (* 9 (factorial 8)))))......(if (= 10 1) 1 (* 10 (if (= 9 1) 1 (* 9 40320))))  (if (= 10 1) 1 (* 10 362880))(if (= 10 1) 1 3628800)(3628800) 

if 是正则序 (Scheme解释器是用正则序的)

(factorial 10)(if (= 10 1) 1 (* 10 (factorial 9)))(* 10 (factorial 9)) (* 10 (if (= 9 1) 1 (* 9 (factorial 8))))(* 10 (* 9 (factorial 8))) ......(* 10 (* 9 (* 8 (* 7 (* 6 (* 5 (* 4 (* 3 (* 2 (1))))))))))......(3628800)

关键词: 子表达式 函数调用