【问题标题】:LISP arithmetics implementationLISP 算术实现
【发布时间】:2015-10-05 14:21:09
【问题描述】:

我正在用 D 做一个玩具 lisp 解释器,但我不太了解 Lisp 的理论。

我想知道 Lisp 是否可以自己实现基本的算术函数(+、-、×、÷)。 大多数 Lisp/Scheme 方言使用 C 类 Java 语言的内置函数实现它,并将其重载为 lisp 代码(重复实现?)。

我想纯粹用 Lisp 代码编写算术函数。 有可能吗?

【问题讨论】:

    标签: c lisp arithmetic-expressions


    【解决方案1】:

    除非您想使用Church numerals 或类似的东西,否则在某些时候您将不得不以一种方式进入硬件算术指令(addsubmuldiv)或其他。

    如果走硬件指令路线,那么根据您的 Lisp 实现,它可能使用 C 代码实现(特别是对于基于解释器的实现),或者可以直接发出这些指令(对于基于 JIT 编译器的实现)。

    如果您想尽可能地遵循第一原则,您可以使用加法和减法指令来实现乘法和除法(在紧要关头,您可以像在学校教的那样实现它们,尽管您'重新使用字大小的数字——也就是说,对于 32 位机器,每个数字都是 base-4294967296 而不是 base-10)。

    【讨论】:

      【解决方案2】:

      非常简单的解决方案将始终使用您的主机数字塔,但我理解您希望保持低原语的愿望。然而,结果是像第一批 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 上使用了它,它只有列表和符号。

      【讨论】:

        【解决方案3】:

        如果你有兴趣在 Lisp 中实现 bignums,我可以推荐 André van Meulebrouck 的这个系列:

        https://web.archive.org/web/20101208222557/http://www.mactech.com/articles/mactech/Vol.08/08.03/BigNums/index.html

        上面的链接是 web.archive.org。由于某种原因,仍然存在的原始链接没有显示任何内容(http://www.mactech.com/articles/mactech/vol.08/08.03/bignums/index.html

        【讨论】:

          【解决方案4】:

          所有Peano arithmetic都基于三个函数:

          • 零,在 Lisps 中表示为 zeropzero?,具体取决于方言;
          • 后继者,在 Lisps 中由 add1 表示;如果您的方言没有它,那么无论如何您都必须在引导语言中实现 +;
          • 身份,在 Lisp 中由 equal 表示。

          使用这三个函数,您可以构建整个算术,但这并不容易!

          在我看来,在您的实现语言中构建您的 Lisp 算术原语(加、减、乘、除)是明智的。如果您想拥有一流的比率和大数,尤其如此。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多