【发布时间】:2015-10-05 14:21:09
【问题描述】:
我正在用 D 做一个玩具 lisp 解释器,但我不太了解 Lisp 的理论。
我想知道 Lisp 是否可以自己实现基本的算术函数(+、-、×、÷)。 大多数 Lisp/Scheme 方言使用 C 类 Java 语言的内置函数实现它,并将其重载为 lisp 代码(重复实现?)。
我想纯粹用 Lisp 代码编写算术函数。 有可能吗?
【问题讨论】:
标签: c lisp arithmetic-expressions
我正在用 D 做一个玩具 lisp 解释器,但我不太了解 Lisp 的理论。
我想知道 Lisp 是否可以自己实现基本的算术函数(+、-、×、÷)。 大多数 Lisp/Scheme 方言使用 C 类 Java 语言的内置函数实现它,并将其重载为 lisp 代码(重复实现?)。
我想纯粹用 Lisp 代码编写算术函数。 有可能吗?
【问题讨论】:
标签: c lisp arithmetic-expressions
除非您想使用Church numerals 或类似的东西,否则在某些时候您将不得不以一种方式进入硬件算术指令(add、sub、mul、div)或其他。
如果走硬件指令路线,那么根据您的 Lisp 实现,它可能使用 C 代码实现(特别是对于基于解释器的实现),或者可以直接发出这些指令(对于基于 JIT 编译器的实现)。
如果您想尽可能地遵循第一原则,您可以使用加法和减法指令来实现乘法和除法(在紧要关头,您可以像在学校教的那样实现它们,尽管您'重新使用字大小的数字——也就是说,对于 32 位机器,每个数字都是 base-4294967296 而不是 base-10)。
【讨论】:
非常简单的解决方案将始终使用您的主机数字塔,但我理解您希望保持低原语的愿望。然而,结果是像第一批 LISP 这样的语言在性能方面表现不佳。
作为 Chris's Church 数字的替代方法,您可以使用列表对数字进行建模。例如。 1234 可以是 (+ 4 3 2 1)。现在,您要么将低数字类型作为原始类型,要么您看到的数字只是您的数学函数知道的自我评估符号。如果你有一个低数字类型,你可以添加一个指数,这样它就变成了(+ 0 4 3 2 1) 对应于1234 和(+ 1 4 3 2 1) 对应于12340 和(+ -11 4 3 2 1) 对应于0.00000001234。所有算术都是使用您在学校知道的数学的列表迭代。它比 Church 数字更有效,效率略高,而且更容易打印和阅读。
我在我的little lisp interpreter 上使用了它,它只有列表和符号。
【讨论】:
如果你有兴趣在 Lisp 中实现 bignums,我可以推荐 André van Meulebrouck 的这个系列:
上面的链接是 web.archive.org。由于某种原因,仍然存在的原始链接没有显示任何内容(http://www.mactech.com/articles/mactech/vol.08/08.03/bignums/index.html)
【讨论】:
所有Peano arithmetic都基于三个函数:
zerop 或 zero?,具体取决于方言;add1 表示;如果您的方言没有它,那么无论如何您都必须在引导语言中实现 +;equal 表示。使用这三个函数,您可以构建整个算术,但这并不容易!
在我看来,在您的实现语言中构建您的 Lisp 算术原语(加、减、乘、除)是明智的。如果您想拥有一流的比率和大数,尤其如此。
【讨论】: