学习一种 Lisp 语言是否有助于学习其他 Lisp 语言?

9
是否有学习不同Lisp语言的协同作用?我目前正在学习Emacs Lisp,因为它在我的日常Emacs使用中立即有用,但我对所有Lisps都很着迷,所以也许有一天我会学习和使用其他Lisp。当我开始深入研究Common Lisp、Scheme或Clojure时,学习Emacs Lisp会帮助我吗?换句话说,对我来说,这是否像学习一门全新的语言,还是某些概念和范例是共通的?我还对比较Lisps之间的独特差异很感兴趣,当我从一个Lisp转到另一个Lisp时会遇到问题。
如何学习Common Lisp和Emacs Lisp?中提到会有"浪费",但没有详细说明程度。

4
自己实现 Lisp 一定有助于学习其他 Lisp。 - SK-logic
2个回答

18
如果您想学习一些旧版Lisp的基础知识,那么Emacs Lisp就可以了。
- Emacs Lisp:可在Emacs中使用。开发环境已包含。是主流Lisp的旧方言。缺少很多概念。有许多用于编辑器编程的扩展。Common Lisp和Emacs Lisp共享一些直接的遗产(命名、概念等)。 - Common Lisp:有很多好书可供学习。可以通过Common Lisp学习很多Lisp概念(包括面向对象编程)。强烈推荐。Common Lisp内置了最重要的Lisp设施,库提供了其余部分。周围有大量的东西可以学习。 - Scheme:70年代创建的不同Lisp方言。与Emacs Lisp或Common Lisp不直接兼容。有很多优秀的书籍和其他教程材料。强烈推荐学习Lisp基础知识和一些更高级的内容。你越深入地挖掘Scheme,它看起来就越不同于Emacs Lisp甚至Common Lisp。 - Clojure:非常不同的Lisp方言。与Common Lisp、Emacs Lisp或Scheme不兼容。共享一些概念,某些概念的工作方式不同。有好书。如果您想学习一些Lisp或特别是Clojure,强烈推荐。Clojure强调函数式和并发编程-非常相关的主题。 如果您想学习更多主流Lisp(具有典型Lisp方言的外观和感觉),我建议使用Common Lisp或Scheme。 对于学习Lisp的语言偏好(!),我的排序如下:
1. Common Lisp 2. Scheme 3. Clojure 4. Emacs Lisp 举个例子:
这是1960年写成的McCarthy's Lisp中的COLLAPSE函数(来自Lisp I Programmer's manual, 1960,第101页)。它基本上是许多Lisp练习中的FLATTEN函数。它获取一个嵌套列表,并返回一个新列表,其中原子在单个列表中。
DEFINE
(((COLLAPSE,(LAMBDA,(L),(COND,
   ((ATOM,L),(CONS,L,NIL))
  ((NULL,(CDR,L)),
     (COND,((ATOM,(CAR,L)),L),(T,(COLLAPSE,(CAR,L)))))
   (T,(APPEND,(COLLAPSE,(CAR,L)),(COLLAPSE,(CDR,L)))))
))))))

这是Common Lisp版本。你可以保持它为大写或转换为小写。两种方式都可行。
(DEFUN COLLAPSE (L)
  (COND 
   ((ATOM L) (CONS L NIL))
   ((NULL (CDR L))
    (COND ((ATOM (CAR L)) L)
          (T (COLLAPSE (CAR L)))))
   (T (APPEND (COLLAPSE (CAR L))
              (COLLAPSE (CDR L))))))

基本上是一样的。只有定义函数的形式有不同的名称和语法。否则代码完全相同。

试试在Common Lisp中使用麦卡锡的示例:

CL-USER > (COLLAPSE '(((A B) ((C))) ((D (E F)) (G) ((H)))))
(A B C D E F G H)

它运行了。

现在让我们尝试在使用GNU Emacs的Emacs Lisp中运行它。Emacs Lisp使用小写标识符:

ELISP> (defun collapse (l)
         (cond 
           ((atom l) (cons l nil))
           ((null (cdr l))
            (cond ((atom (car l)) l)
                  (t (collapse (car l)))))
           (t (append (collapse (car l))
                      (collapse (cdr l))))))

ELISP> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)

这段代码可以在不做任何改变的情况下在Emacs Lisp中运行。

你也可以在Scheme中获得类似的版本(只需进行轻微的重命名):

Petite Chez Scheme中:

> (define collapse
    (lambda (l)
      (cond 
        ((atom? l) (cons l '()))
        ((null? (cdr l))
         (cond ((atom? (car l)) l)
               (else (collapse (car l)))))
        (else (append (collapse (car l))
                      (collapse (cdr l)))))))

我们可以使用 DEFINE 来定义一个函数。而 COND 稍微有些不同,() 表示空列表。谓词(判断条件)后面加上了 ? 符号。
> (collapse '(((a b) ((c))) ((d (e f)) (g) ((h)))))
(a b c d e f g h)

运行。

在Clojure中,它看起来会有所不同。 基本上,您必须重新思考大部分代码。

这是Clojure自己实现的flatten

(defn flatten
  [x]
  (filter (complement sequential?)
          (rest (tree-seq sequential? seq x))))

你可以按照Lisp版本的精神编写flatten函数 - 它看起来仍然会有所不同。
来自rosetta.org
(defn flatten [coll]
  (lazy-seq
    (when-let [s  (seq coll)]
      (if (coll? (first s))
        (concat (flatten (first s)) (flatten (rest s)))
        (cons (first s) (flatten (rest s)))))))

名称不同,语法不同,语义不同(适用于惰性序列而非列表)。

像Common Lisp、Emacs Lisp、Visual Lisp、ISLISP等方言试图保留其遗产。

Scheme或Clojure等方言并不感到受名称和语法的约束。它们在各个方向上进行了创新。Scheme仍然提供了旧功能的直接版本。Clojure没有。Clojure程序员不会认为这是一个劣势。


2
嗯。我对这个偏好顺序唯一的问题是它似乎没有优先考虑即时实用性 - 这是Clojure闪耀的领域之一; 在工作场所中使用基于JVM的语言的实际机会很容易找到(虽然存在一些基于JVM的Scheme实现,但几乎没有可比的互操作性),而可用于Clojure的库的广度远远优于任何特定Scheme实现可用的内容(当一个人开始尝试做实际工作时,在那个世界中的分裂变得非常不幸)。 - Charles Duffy
6
是的,我强烈不同意Rainer认为Common Lisp / Scheme是“更主流”的Lisp。别误会,我喜欢CL,但Clojure目前是最实用的Lisp。例如,比较使用ASDF和使用Leiningen/Clojars的简易程度(以及对所有Java Maven存储库的访问同样简单)。CL开发实践有些过时,例如每个人都使用每个库的最新trunk版本。Clojure库往往经过充分测试,版本化,在github上/容易贡献。CL库通常是孤独的业余项目,最后一次更新是几年前。 - rplevy
2
@CharlesDuffy:我强烈反对,Common Lisp专注于可用性。如果您想与JVM交互,请查看[ABCL](http://common-lisp.net/project/armedbear/); 如果您想与C交互,请查看[CFFI](http://common-lisp.net/project/cffi/)。而[Practical Common Lisp](http://common-lisp.net/project/cffi/)是一本很棒的教程。 - Daimrod
1
@RainerJoswig 确实,JVM 上有许多 Scheme 实现 - 但正如我所说,很少有实现具有可比的互通性。Clojure 的 Java 互通性支持诸如装饰器之类的功能,这些功能最近才添加到 JVM 中; 我不知道有哪些基于 JVM 的方案在保持同步方面效果如此显著。 - Charles Duffy
2
@Daimrod 说实话,ABCL 的开发者社区只有大约10人,而Clojure则拥有庞大的势头,拥有数千名开发者和相当数量的商业部署。 - rplevy
显示剩余4条评论

15

是的——如果您已经懂得Lisp,那么学习新的Lisp语言会更加容易。

原因如下:

  • 您将理解“代码即数据”及应用于同构语言的元编程的概念(这可能是Lisp与其他语言最大的不同点)。
  • 您将更轻松地阅读Lisp语法。需要几周时间才能达到“看到”Lisp代码结构的程度,但此后,情况将变得更加容易。您开始忽略括号。
  • 开发风格类似,都是使用REPL与正在运行的环境进行交互。
  • 他们共享常见的惯用语,例如列表和各种函数式编程技术的使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接