17

每个 Common Lisp 程序员都知道宏是一个强大的工具。通用 Lisp 宏已被用于在 Lisp 之上添加面向对象而不改变语言规范;读取宏是另一种具有思维弯曲功能的构造。

另一个允许元编程的程序是 Forth。Forth 使用“单词”和“生成单词”的方式略有不同。

我想从涉足两种语言的人那里知道,如果常见的 lisp 宏和 forward 构造在广度/功能上是可比的:有没有你可以用前者做的事情,而你不能用后者做些什么?或相反亦然?

当然,我不是在谈论这两种语言的图灵完备性:我是在谈论元编程能力。C 是图灵完备的,但只有傻瓜才会说 C 宏在功能上与 Common Lisp 相当。

4

3 回答 3

9

在我看来,Common Lisp 宏类似于 Forth立即字。(实际上,它们与 Lisp 阅读器宏最相似。)

  • 它们都是过程宏,即可以使用语言的全部功能。

  • 他们都可以访问源代码输入。

  • 他们都可以输出任何可以用语言表达的东西。(例如,Lisp 中的面向对象扩展,或 Forth 中的基本控制流结构。)

主要区别可能在于 Forth 的“宏”输入是字符串,而 Lisp 宏在解析树上运行。

于 2014-06-18T09:54:37.647 回答
9

我是一名 Forth 实现者,在 Forth 方面拥有丰富的经验,有六种实现,几百个 projecteuler 问题。我还做了一个小的面向对象的扩展(小,即十几行左右)。我在 LISP 方面的经验更多是在课程层面,但我认为可以说 LISP 的元编程工具更系统,在实践中更强大。

在 LISP 的抽象之上构建抽象相对容易。在 Forth 中,如果我想在由具有非平凡定义的对象定义的线性空间上定义一个矩阵。我切换到 Python。

原因也很明显,至少对我来说是这样。LISP 的创造者是数学家,而 Chuck Moore 是实际程序员的终极典范,从不将时间浪费在理论问题上。

这通过以下方式延伸到这个问题。lisp 宏在 Lisp 上下文中具有结构,并且至少暗示了符合一般 lisp 原则的含义。Forth 直接词只是另一个程序,可以表示和做任何事情,包括用它做一顿狗晚餐。

于 2015-02-09T22:38:36.250 回答
3

对不起,如果下面的讨论可能看起来有点模糊,但要说的太多了。

我只有 Lisp 的理论知识,没有动手。

另一方面,Forth 可以(但普通的 Forth 没有)语言内部的完整元编程。但是元编程是可以考虑和可能的,但没有连贯的语法。我认为在 Lisp 中也会发生同样的情况。

我已经实现了一个非常干净的解决方案,其中包括在类似 Forth 的小型语言范式中的可能性。为了进行元编程,我们应该能够参考我们所写的内容。因此,当我们编写要立即执行的程序时:

bread eat

我们也应该能够在意图中引用相同的短语,而不是执行它以保留它以供以后参考。这可以通过写作来完成,例如

{ bread eat } 

上面的短语可能会导致将创建的对象留在堆栈上。但是,当我们创造了一个新词 as 时{}我们也有权引用它。

所以,我们可以参考:

{ bread 

我们怎么能提到那个?暂定语法是:{{ { bread }}.

如果我们给XXX前一个短语命名,我们可以将初始短语写成:

XXX eat }

并且上面的短语应该可以正确地留在堆栈上

{ bread eat }

因为我不知道我所说的是否正是您要寻找的内容,所以只要说通过上述推理及其在 Forth 中的实现就足够了,每个单词都有一个执行级别,并定义了哪个是该单词的元编程级别.

显然,我们有第一个无穷级别和每个后续级别。所以执行级别是基于数学无穷大的。

我已经在一种 Forth 中实现了上述内容,并且在第一级(无限远)一切正常。因此,例如,我能够更改以下语法:

{ bread eat } { tomatos eat } x 3 = if 

进入:

{ bread eat | tomatos eat } x 3 = if 

这是通过定义|如下来完成的} {

{{ } { }} "|" define

或者如果你更喜欢它:

2{ } { 2} "|" define 

上面的方法以正确的语法将元语言纳入语言并将其变成语言。

所以在我看来,Lisp 和 Forth 都有元编程的可能性,但都缺乏作为语言集成部分的可能性。

我在napl.wikispaces.com上有更多详细信息。

于 2014-07-28T23:52:19.737 回答