在第二篇文章里我们还留下许多未实现的内置函数 如标题 的if,不过这次我们并不打算通过内置函数的方式去实现if,那么还有其他办法吗,当然是有的,如标题那就是通过布尔逻辑 与或非,还有之前已经实现的 let、lambda、 apply、 var、cons让我们开始吧。
准备工作
布尔逻辑
首先我们先检查一下我们已有的布尔逻辑
- and: 当所有子结构的值都是真时,and的返回值是真,实际上,and的运行结果是最后一个子结构的值。如果任何一个子结构的值都是假,则返回#f。
- or: 会返回它第一个为值为真的子结构的结果。如果所有的子结构的值都为假,or则返回#f。
- 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个小时的时间才想明白这一切。
总结
很多时候通过直接的方式并不能得到符合我们期待的结果,有时只需要增加一个中间层即可,当然也可以是多个,我想编程是如此,生活亦是如此。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。