在第二篇文章里我们还留下许多未实现的内置函数 如标题 的if,不过这次我们并不打算通过内置函数的方式去实现if,那么还有其他办法吗,当然是有的,如标题那就是通过布尔逻辑 与或非,还有之前已经实现的 let、lambda、 apply、 var、cons让我们开始吧。

准备工作

布尔逻辑

首先我们先检查一下我们已有的布尔逻辑

  1. and: 当所有子结构的值都是真时,and的返回值是真,实际上,and的运行结果是最后一个子结构的值。如果任何一个子结构的值都是假,则返回#f。
  2. or: 会返回它第一个为值为真的子结构的结果。如果所有的子结构的值都为假,or则返回#f。
  3. not 对结果取反

定义if结构

(if predicate then_value else_value)

编码实现

只需要一行代码

(let ((if (lambda (p then_v else_v) ((or (and p car) cdr) (cons then_v else_v))))) (..))

核心代码

(lambda (p then_v else_v) ((or (and p car) cdr) (cons then_v else_v)))

让我们看一下布尔逻辑的部分

(or (and p car) cdr)

先是and,如果p为真返回car, 然后是or,如果p为假返回cdr;也许你会问为什么car 不换成 then_v,cdr不换成 else_v呢,原因在于 第一个的and 假设p为真时, 如果 then_v 的值是false 会发生什么呢? 我们会发现 then_v 与 else_v 都被执行了,问题的关键就是 then_v 有可能是false 或0, 因此我们换个思路,如果p为真返回第一个值否则返回第二个值 既然值有可能会是假,那么值为真是不是就正常了呢?答案是是的,因此我们需要一点魔法,我们在值外面包裹一层永远是true 的值即可,然后使用时在把包裹去掉即可,显然有一个方法可以帮助我们它是cons也可以是其他,但这一切并不是显而易见的,我花费了1个小时的时间才想明白这一切。

总结

很多时候通过直接的方式并不能得到符合我们期待的结果,有时只需要增加一个中间层即可,当然也可以是多个,我想编程是如此,生活亦是如此。


yangrd
1.3k 声望225 粉丝

代码改变世界,知行合一。