首页 > 其他分享 >Lisp的求值规则

Lisp的求值规则

时间:2023-01-20 18:33:34浏览次数:42  
标签:10 square ... Lisp factorial 规则 求值 表达式

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)

标签:10,square,...,Lisp,factorial,规则,求值,表达式
From: https://www.cnblogs.com/iceshadow/p/17062998.html

相关文章

  • steed - 自制Lisp方言实现
    之前有网友提到写Lisp,我也挺感兴趣的,最近写了一个,主要参考PracticalCommonLisp和SuccessfulLisp这两本书,读到哪实现到哪。求值和解析实现了,特性方面是包括letbinding,......
  • layUI自定义校验规则
    layUI自定义校验规则howtomakeit69于2021-10-2707:30:00发布1704收藏3文章标签:layui前端uijavascript版权在使用layUI这款开源模块化前端UI框架是,如......
  • Java命名规则 方法名用驼峰 ;类首字母大写;方法全小写
    类命名规则 1.由字母、下划线、美元符号和数字组成,长度不限 2、首字符不能是数字3、不能是关键字4、不能是true、false和null,尽管这三个不是关键字5、区分大小写的......
  • webFlux routers 嵌套路由解析规则
    有下列路由publicRouterFunction<ServerResponse>doctorRoutes(DoctorHandlerhandler){returnRouterFunctions.route().path("/doctors"......
  • C/C++四则运算表达式的求值系统[2023-01-18]
    C/C++四则运算表达式的求值系统[2023-01-18]四则运算表达式的求值系统设计(四选一选做部分)(1)结合基本操作,建立运算表达式的二叉树,输出树的前中后序遍历的结果,例如[(31-23)......
  • 《ClickHouse原理解析与应用实践》关于P239[分片规则]错误的地方
     《ClickHouse原理解析与应用实践》关于P239[分片规则]错误的地方 快过年了,坚守到最后一天。刚好开发有新的想法,需要用到ReplacingMergeTree引擎实现去重或删除数据......
  • HummerRisk V0.9.0:增加RBAC 拓扑图,云检测、漏洞、主机等模块增加规则
     HummerRiskV0.9.0发布:增加RBAC资源拓扑图,首页新增检查的统计数据,云检测、漏洞、主机等模块增加规则,对象存储增加京东云,操作审计增加金山云,镜像仓库新增设置别名。感谢社......
  • UNIQUE约束添加规则
    UNIQUE约束添加规则1、唯一约束确保表中的一列数据没有相同的值。2、与主键约束类似,唯一约束也强制唯一性,但唯一约束用于非主键的一列或者多列的组合,且一个表可以定义多......
  • Spring Cloud Alibaba——Sentinel规则持久化
    一、在生产环境中使用Sentinel生产环境的SentinelDashboard需要具备下面几个特性:1、规则管理及推送,集中管理和推送规则。2、监控,支持可靠、快速的实时监控和历史监控数......
  • python按规则打印一组数字
    代码块forindex,ballinenumerate(balls):print(f'{ball:0>2d}',end='')ifindex==len(balls)-2:print('|',end='')enumerate()enumera......