计算机程序的构造和解释 - 个人笔记(一)(下)

简介: 计算机程序的构造和解释 - 个人笔记(一)(下)

Sicp简单了解



基本语法:


(+ 3  8)
(* 3 (+ 7 19.5))
(+ (+ 5 4) (* 6 (- 9 4)))
复制代码


  1. 3 + 8 的和
  2. 3 * (7 + 19.5)


定义:


组织函数:

最简单的组织一个定义方式


(define (square x) (* x x))
复制代码


使用lambda表达式


(define square (lambda (x) (* x x)) )
复制代码


定义的组织函数本身也可以作为内容的一部分


(define (sq x) (* x x))
  (define (sum x y) (* (sq x) (sq y)))
复制代码


这样设计的好处:

  1. 可以让程序员灵活的搭配组织简单的程序形成复杂的程序
  2. 没有语言的约束,只有基本的语法规则

坏处:

  1. 你无法知道哪些是定义,哪些是引用
  2. 程序的可读性较差


条件语句:


cond:可以理解为switch ( (p1 p2) (p3 p4) (p5 p6) )

如果没有唯一的一个cond 的值,则cond 会没有定义


cond (<p1> <e1>)
    (<p2> <e2>)
             .......
            (<pn> <en>))
或者
(cond (<p1> <e1>)
    (<p2> <e2>)
             .......
            (else <en>))
复制代码


应用:


(define (sq3 y)
  ((cond ((> y 0) y)
  ((= y 0) 0)
  ((< y 0) (- y)))))
复制代码


另一种写法:


(define (sq5 k)
  (cond ((< k 0) (- k))
  (else k)))
复制代码


if:是一种语法糖:


(define (zz x)
  (if (> x 0)
      (-1)
      x))
复制代码


  1. 把自己的作为结果,带入到函数当中求值返回
(and  ..... )


(define (test t) 
  (and  (> t 5) (< t 1)))
复制代码


(or ..... )


(define (test t) 
  (or (> t 5) (< t 1)))
复制代码


(not ..... )


(define (test t) 
  (not (> t 5) (< t 1)))
复制代码


什么是正则序求值,什么是应用序求值


结论:Lisp使用的是应用序求值

正则序求值:使用过程组合,层层的代换展开运算,最后完全展开运算完成的这个过程就叫做正则序求值(可以理解为懒加载,在只有实际使用到参数的时候,才会带入参数运算)

应用序求值:应用序求值,先对每一个形式参数带入实际的值进行实际的运算操作,直到返回最终结果

为什么Lisp使用应用序求值?


  1. 减少没有必要的计算,比如说正则序列求值,需要将一步完成的计算继续拆分为更多步骤
  2. 正则的结果不一定完全正确(特殊案例)

课后练习:


网络异常,图片无法展示
|


非常好的一个问题:


在定义的时候,如下面所示的括号有无的区别


(define (d) (* 5 5))
(define d (* 5 5)) 
> 输入 a = 5
结果 25
> 输入 d = 5
结果 25
两者内部的细节区别:
(define (d) (* 5 5)) -> 运行的是一个复合公式
(define d (* 5 5))  -> 函数的结果
复制代码


课后练习 1.2


(/ (+ 5 4 (-2 (-3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7)))
复制代码


解决思路:其实挺简单的,画树就行


课后练习 1.3


题目:求较大两数的两树之和?

分析:

使用双层if判断

拆分


(define (maxVal3 x y z)
  (if (> x y)
      (if (> y z) (* x y)
          (* x z))
      (* z y)))
复制代码


课后练习 1.4


(define (a-plus-abs-b a b) ((if (> b 0) + -) a b))
复制代码


  1. if (b > 0)
  1. + a b
  1. if(b < 0)
  1. - a b


解答:


可知,由于(define (p) (p)), 如果出现了对(p)求值的情况, 就会陷入循环 scheme中的解释器本身就是应用序的,函数的求值会先对每一个参数进行求值,     然后把参数的值代入函数,若对(test 0 (p))使用应用序,那么(p)就会被求值,      进入死循环中。而正则序是“完全展开而后规约”,在展开之后,由if条件判断,然后      对0求值,由于(p)不会进行求值,最终函数可以正确返回0值。 (Guile中测试此程序确会进入死循环。)

PS:这一段网上摘录的答案还不是很了解,还没有进行实际的验证

相关文章
|
消息中间件 存储 缓存
一文了解清楚kafka消息丢失问题和解决方案
今天分享一下kafka的消息丢失问题,kafka的消息丢失是一个很值得关注的问题,根据消息的重要性,消息丢失的严重性也会进行放大,如何从最大程度上保证消息不丢失,要从生产者,消费者,broker几个端来说。
692 0
sklearn之pipeline:sklearn.pipeline函数使用及其参数解释之详细攻略
sklearn之pipeline:sklearn.pipeline函数使用及其参数解释之详细攻略
|
关系型数据库 MySQL Linux
Linux下安装Mysql5.7.x数据库
乌班图系统安装mysql过程中遇到的坑,在此记录
|
云计算
阿里云首进Gartner云计算魔力象限,却与亚马逊、微软和谷歌比肩
 本文讲的是阿里云首进Gartner云计算魔力象限,却与亚马逊、微软和谷歌比肩【IT168 云计算】根据外媒财经媒体《巴伦周刊》消息,引述研究机构Gartner的年度云计算魔力象限表示,来自中国的阿里云成为全球云计算技术的领导者,与亚马逊、微软和谷歌并列全球四大云计算服务商。
2173 0
|
3天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
271 116
|
18天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
12天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
662 219