【问题标题】:Does learning one Lisp help in learning the other?学习一种 Lisp 是否有助于学习另一种?
【发布时间】:2012-06-29 22:21:21
【问题描述】:

学习不同的 Lisp 语言之间有什么协同作用吗?我目前正在学习 Emacs Lisp,因为它在我的日常 Emacs 使用中非常有用,但是我对所有 Lisp 都很着迷,所以也许有一天我会学习和使用其他的。 当我开始深入研究 Common Lisp、Scheme 或 Clojure 时,学习 Emacs Lisp 对我有帮助吗? 换句话说,对我来说,这对我来说会不会像学习一门全新的语言一样,或者某些概念和范式很常见?我也对比较 Lisp 之间的独特差异感兴趣,当我从一个 Lisp 到另一个 Lisp 时,这将是一个问题。

How to go about learning Common Lisp and Emacs Lisp?中提到会有“浪费”,但没有详细说明,具体到什么程度。

【问题讨论】:

  • 实现你自己的 Lisp 肯定会有助于学习其他 Lisp。

标签: clojure lisp scheme elisp common-lisp


【解决方案1】:

如果你想学习一些较早的 Lisp 基础知识,那么 Emacs Lisp 就可以了。

  • Emacs Lisp:可以在 Emacs 中使用。包括开发环境。主流 Lisp 的旧方言。缺乏很多概念。有许多编辑器编程的扩展。 Common Lisp 和 Emacs Lisp 有一些直接的继承关系(命名、概念等)。

  • 普通 Lisp。很多好书值得学习。许多 Lisp 概念(包括 OO 编程)可以通过 Common Lisp 学习。强烈推荐。 Common Lisp 内置了最重要的 Lisp 工具,其余部分由库提供。围绕它可以学到很多东西。

  • 方案:70 年代创建的不同 Lisp 方言。与 Emacs Lisp 或 Common Lisp 不直接兼容。许多优秀的书籍和其他教程材料。强烈推荐用于学习 Lisp 基础知识和一些更高级的东西。对 Scheme 的研究越深入,它与 Emacs Lisp 甚至 Common Lisp 的区别就越大。

  • Clojure:非常不同的 Lisp 方言。与 Common Lisp、Emacs Lisp 或 Scheme 不兼容。共享一些概念,一些概念的工作方式不同。好书。如果您想学习一些 Lisp 或特别是 Clojure,建议您使用。 Clojure 强调函数式和并发编程 - 非常相关的主题。

如果你想学习更多主流 Lisp(一种具有典型 Lisp 方言外观和感觉的 Lisp),我会推荐 Common Lisp 或 Scheme。

我学习 Lisp (!) 的语言偏好是:

  1. 普通的 Lisp
  2. 方案
  3. Clojure
  4. Emacs Lisp

举个例子:

这是 McCarthy's Lisp 中的 COLLAPSE 函数,写于 1960 年(来自 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 中尝试 McCarthy 的示例:

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 程序员不会将此视为劣势。

【讨论】:

  • 嗯。我对这个优先顺序的唯一问题是它似乎没有优先考虑即时实用性——Clojure 的一个亮点;很容易找到在工作场所使用基于 JVM 的语言的实际机会(虽然存在一些基于 JVM 的 Scheme 实现,但很少有类似的互操作性),而且 Clojure 可用的库的广度远远好于可用的任何特定的 Scheme 实现(当一个人开始尝试做实际工作时,这个世界的碎片化变得非常不幸)。
  • 是的,我非常不同意 Rainer 的观点,即 Common Lisp / Scheme 是“更主流”的 Lisp。不要误会我的意思,我喜欢 CL,但 Clojure 是迄今为止最“真实世界”的 Lisp。例如,比较使用 ASDF 的难度与 Leiningen/Clojars 的易用性(以及对所有 Java maven 存储库的同样简单的访问)。 CL 开发实践有点落后,例如每个人都使用每个库的最新主干。 Clojure 库往往在 github 上经过良好测试、版本控制/直接贡献。 CL 库通常是孤狼爱好项目,最近一次更新是几年前
  • @CharlesDuffy:我强烈反对,Common Lisp 专注于可用性。如果您想与 JVM 交互,请查看 ABCL,如果您想与 C 交互,请查看 CFFIPractical Common Lisp 是一个很棒的教程。
  • @RainerJoswig 确实,JVM 有很多 Scheme 实现——但正如我所说,几乎没有类似的互操作性。 Clojure 的 Java 互操作支持最近才添加到 JVM 中的装饰器等特性;我不知道有任何基于 JVM 的方案能够有效地跟上进度。
  • @Daimrod 公平地说 ABCL 拥有一个大约 10 人的开发者社区,而 Clojure 拥有巨大的发展势头,拥有数千名开发者的社区和大量的商业部署。
【解决方案2】:

是的 - 如果你已经知道一个新的 Lisp,那么选择一个新的 Lisp 会容易得多。

原因:

  • 您将了解“代码即数据”的概念和同音语言中的元编程(这可以说是使 Lisps 与其他语言独特/不同的最大单一因素)
  • 您将能够更轻松地阅读 Lisp 语法。需要几周的时间才能“看到” Lisp 代码的结构,但在那之后它会变得容易得多。一段时间后,您开始忽略括号。
  • 开发风格类似,使用 REPL 与运行环境交互
  • 它们有共同的习语,例如使用列表和各种函数式编程技术

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    • 2010-11-03
    • 2017-09-20
    • 2011-01-08
    • 1970-01-01
    • 2018-06-16
    • 2019-09-14
    相关资源
    最近更新 更多