LISP宏能走多远?

我已经读了很多,LISP可以重新定义语法,大概是用宏。我很好奇它到底有多远?你能否重新定义语言结构以使其边界成为另一种语言的编译器?例如,你是否可以将LISP的功能特性改变为面向对象的语法和语义,也许可以说语法接近于Ruby这样的语法?

尤其是,是否有可能使用宏摆脱括号地狱?我已经学会了足够多的(Emacs-)LISP来用我自己的微功能来定制Emacs,但是我非常好奇宏定制语言的程度。

0
额外 编辑
意见: 1
Scheme宏非常强大。我作为Scheme宏写了一个完整的LINQ实现。 https://ironscheme.svn.codeplex.com/svn/ IronScheme / IronSchem‌ eConsole / ironscheme /‌ linq.ss 拥有所有这些力量,我将会用尽所有想法来应用它!
额外 作者 leppie,
Peter Norvig 制作了 Prolog Interpreter 在他的中。
额外 作者 Özgür,
请注意,lisp是面向对象的。请参阅Common Lisp对象系统。
额外 作者 catphive,

7 答案

@sparkes

有时LISP是明确的语言选择,即Emacs扩展。我确定我可以使用Ruby来扩展Emacs,但是Emacs可以用LISP进行扩展,所以在这种情况下使用它似乎是有意义的。

0
额外

如果你想Lisp看起来像Ruby使用Ruby。

有可能以一种非常清晰的方式使用Ruby(和Python),这是他们如此迅速获得接受的主要原因之一。

0
额外

这是一个棘手的问题。由于lisp在结构上已经非常接近解析树,因此大量宏和在解析器生成器中实现自己的迷你语言之间的区别并不十分清楚。但是,除了开幕式和闭幕式之外,您可能很容易就会看到一些看起来不像lisp的东西。

0
额外
“除了开幕式和闭幕式之外”< - 你甚至可以改变这一点。请参阅星球标准ML嵌入Scheme(Racket)中,使用Scheme的等效读写器宏。
额外 作者 p4bl0,

常规宏对对象列表进行操作。最常见的是,这些对象是其他列表(从而形成树)和符号,但它们可以是其他对象,如字符串,哈希表,用户定义的对象等。这些结构称为 s-exps

所以,当你加载一个源文件时,你的Lisp编译器将解析文本并产生s-exps。宏对这些进行操作。这非常有效,它是在s-exps精神下扩展语言的一种奇妙的方式。

另外,前面提到的解析过程可以通过“读取器宏”进行扩展,使您可以自定义编译器将文本转换为s-exps的方式。不过,我建议你接受Lisp的语法,而不是将它弯曲成其他东西。

当你提到Lisp的“功能性”和Ruby的“面向对象语法”时,你听起来有点困惑。我不确定应该使用什么“面向对象语法”,但Lisp是一种多范式语言,它很好地支持面向对象的编程。

顺便说一下,当我说Lisp时,我的意思是 Common Lisp

我建议你放弃偏见,并给Lisp一个诚实的去

0
额外

我不是一个Lisp专家,我甚至不是一个Lisp程序员,但经过一段时间的语言试验后,我得出结论,一段时间之后,括号开始变为“隐形”,并且您开始将代码视为你想要它。您开始更加关注通过s-exprs和macros创建的语法结构,而不是列表和括号文本的词法形式。

如果你利用一个好的编辑器来帮助缩进和语法着色(尝试将圆括号设置为与背景非常相似的颜色),这尤其如此。

您可能无法完全替换该语言并获得'Ruby'语法,但您并不需要它。由于语言的灵活性,如果你愿意,你可以结束一种方言,觉得你正在遵循'Ruby风格的编程',无论这对你来说意味着什么。

我知道这只是一个经验观察,但我认为我有一个Lisp启蒙时刻,当我意识到这一点时。

0
额外

是的,你可以从根本上改变语法,甚至可以逃脱“括号里的地狱”。为此,您需要定义一个新的阅读器语法。看看读者宏。

然而,我怀疑要达到Lisp专业水平来编程这些宏,您需要沉浸在语言中,以至于您不再考虑括号“地狱”。即当你知道如何避免它们时,你会接受它作为一件好事。

0
额外

这是一个非常好的问题。

我认为这是微妙的,但绝对可以回答:

宏不会卡在s表达式中。请参阅LOOP宏,了解使用关键字(符号)编写的非常复杂的语言。所以,虽然你可以用圆括号开始和结束循环,但它内部有它自己的语法。

例:

(loop for x from 0 below 100
      when (even x)
      collect x)

话虽如此,大多数简单的宏只是使用s表达式。而且你会“卡住”使用它们。

但是,像塞尔吉奥回答的那样,s表达式开始感觉不错。语法不复存在,并开始在语法树中进行编码。

至于读者宏,是的,你可以想象写这样的东西:

#R{
      ruby.code.goes.here
  }

但是你需要编写你自己的Ruby语法分析器。

您还可以使用编译为现有Lisp结构的宏来模拟一些Ruby结构,如块。

#B(some lisp (code goes here))

将转化为

(lambda() (some lisp (code goes here)))

有关如何操作,请参阅此页面

0
额外
你的宏“不卡在s表达式”中的例子看起来像是s表达式。
额外 作者 Hugh Allen,
循环宏的例子是一个s-expr,但是“子表达式”不是。
额外 作者 Eric Normand,