Haskell是一种Lisp语言吗?

32

我一直在阅读Doets和Eijck 2004年的《Haskell之路:逻辑、数学和编程》。这似乎是一本备受尊重的书,但当它声称Haskell是Lisp家族的成员时,我很吃惊。这是否准确?我认为Lisps具有s表达式、不纯函数和列表作为唯一的复合数据结构。Haskell没有这些特点。对于这种说法有什么正当理由吗?


2
没有!他们正在进行一般性介绍,并说“作为一种函数式语言,Haskell与ML、Occam和Clean一起属于Lisp家族”。 - Bob Bobson
3
那太荒谬了。Lisp可能是第一个函数式语言,但这并不意味着所有的函数式语言都是Lisp,就像Java不是Smalltalk,Python也不是C一样。此外,除了你列出的Haskell缺乏的特性之外,Lisp几乎没有Haskell的高级功能(例如:单子Monad、代数数据类型以及模式匹配)。 - user395760
9
在Lisp中,列表并不是唯一的复合数据结构。它们只是被用于语法树而已。 - Svante
2
这难道不是一个“我很好奇其他人是否和我一样”的问题吗?根据FAQ,应该“避免”这些问题。 - Ken
1
@delnan:“Lisp”实际上是一系列的编程语言,其中一些具有非常先进的功能(请查看Qi和Shen)。 - Tikhon Jelvis
显示剩余5条评论
9个回答

43

Lisp是一个非常模糊的概念。我看到两个或多或少有用的解释:

  1. Lisp是一组共享某些共同思想的语言家族。在广义解释中,属于这个家族的语言非常不同:Common Lisp、Scheme、Logo、Dylan、Emacs Lisp、Clojure、RLisp、3Lisp等等。

  2. Lisp是一系列实现核心语言(CAR、CDR、CONS、LAMBDA、PROG、SET、SETQ、QUOTE、DEFUN、IF、COND、DO等)的语言的血统:Lisp 1.5、MacLisp、Lisp Machine Lisp、Emacs Lisp、Common Lisp、ISLisp。请注意,这些语言通常都将“Lisp”作为其名称的一部分。

一些Lisp方言中的典型事物包括:严格评估、副作用、直接命令式编程、函数编程结构、s表达式、宏展开。

Haskell是一种非常不同的语言:非严格评估、语法不基于s表达式、静态类型、纯函数式。

Haskell既不符合1也不符合2。因此,我会说Haskell不是Lisp。

类似地,我们可以说一个函数式编程语言是:

  1. 支持函数式编程的语言:Lisp、APL、...、ML、SML、OCAML、F#、Miranda、Haskell等。

  2. 强制执行函数式编程的语言。在这方面,Lisp已经不是很适合了,因为命令式甚至面向对象编程在Lisp中并不是二等公民。

  3. 强制执行纯函数式编程的语言。在这里,我们有Haskell作为一个很好的例子。作为相对较新的Lisp方言之一,Clojure也可能适合。

通常,Lisp只支持,但不强制执行函数式编程。因此,在更广泛的解释下,它是一种函数式编程语言。

Haskell是被视为一种纯函数式编程语言之一。


12
除去语法本身,JavaScript 更像 Lisp 而不是 Haskell。它最初的构想是作为 Scheme 的实现。 - Kevin Cantu
9
@Kevin Cantu: 这并非偶然。Brendan Eich 在他的网站上提到,Netscape 招聘他的时候承诺让他在浏览器中实现 Scheme 语言。;-) - Rainer Joswig
1
顺便说一句,我认为LISP的一个独特特性——同构性被忽略了(尽管可以从提到s表达式中推断出来)。 - hvr
4
@hvr: 这是因为“同像性(homoiconicity)”是一个在Lisp世界中很少使用的令人困惑的术语。在那里,我们谈论使用符号表达式进行计算(请参阅麦卡锡关于Lisp的原始论文)。有时我们也会谈论“代码即数据”。 - Rainer Joswig

20
我认为将Haskell视为LISP家族成员存在一定牵强,但我猜测推理大概是这样的......

在对编程语言进行分类时,将它们分为两组是有意义的:从FORTRAN衍生出来的语言和非FORTRAN衍生出来的语言。 1958年,“非FORTRAN组”基本上意味着LISP(至少在今天没有灭绝的语言中)。 因此,一段时间以来,编程语言家族树有两个主要分支:FORTRAN后代和LISP后代。 如果这些是唯一的两个选择,那么我会将Haskell放入LISP分支。

然而,许多评论人士认为,诸如ML、Prolog和APL等语言是“突然冒出来的”——引入了足够独特的范例,以至于有自己的谱系。 Haskell显然与ML有关。

作为这种分类的例子,请参见以下编程语言家族树:

O'Reilly's Programming Language Poster

Computer Languages Timeline at levenez.com

HOPL:编程语言的互动名册(Haskell条目)


O'Reilly的链接已经更改,请查看http://cdn.oreillystatic.com/news/graphics/prog_lang_poster.pdf。 - Devon

9
我不会同意这个说法。虽然Lisp影响了Haskell,但它们都是函数式编程语言,Haskell并不是Lisp的派生语言。只要看一下括号的数量你就可以知道。

7
比语法更重要的是类型系统! - Jonathan Sterling

4

我认为Haskell确实是一种Lisp,因为它们都基于λ演算。 Haskell是λ的实现。

尽管大多数人会说Haskell属于ML系列。 ML也基于λ,我知道的所有函数语言也是如此。

在底层中,OCam(来自ML的后代)被编译成组合逻辑(combinatory logic),这是一种等效于λ演算的形式化语言,并由Haskell Curry发明,后来Haskell也以他的名字命名。但是现在似乎使用组合逻辑进行函数语言编译的情况较少,所以我不确定像GHC这样的现代编译器是否仍然使用组合逻辑。

Lisp的语法与λ演算几乎相同,这使得这个家族(Scheme、Clojure等)非常特殊。


1
非常不正式地说,Lisp基本上相当于无类型的λ演算。Haskell则是基于Hindley-Milner类型系统的有类型λ演算。我认为这种区别足以断言Haskell 不是 Lisp。 - mikera

4
人们对于Lisp的定义各不相同。最初的Lisp规范根本没有提到宏,只定义了一小部分原始函数,如果我没记错的话,这些函数如下:
  • cons
  • car
  • cdr
  • cond
  • eq
  • atom
  • and
  • or
  • not
  • nil
可能这不是完整的列表,或者它可能有一些其他成员,但无论哪种情况,John McCarthy's original specification都非常简短。
如果你将Lisp定义为定义了所有这些函数的任何语言,那么大多数现代语言都是Lisp,包括Haskell。
一个更严格和现代的Lisp定义如下:
  • 急切求值
  • 动态类型
  • 不纯函数式
  • 将列表作为主要数据结构的重点

Haskell 不符合前三个特点,它的宏 (Template Haskell) 不遵循代码即数据的范例,虽然列表非常重要,但它们并不是主要的数据结构。

所以我会说不,Haskell 不是 Lisp。


“code-is-data范式”是什么意思?模板Haskell可以操作语法树;还需要什么? - dfeuer

2

Haskell不是Lisp,这两者都有各自的定义。

在我看来,Lisp是一种语言,其中源代码是该语言中有效的结构。

Haskell的源代码不是Haskell中有效的结构,因此它们必须有一个单独的语法(Haskell模板)来操作自己的源代码。

但是,Haskell中有至少一个有趣的特性让我想起了Lisp。那就是函数调用的语法:func args1 agr2 arg3。Lisp也有完全相同的语法:(func args1 agr2 arg3)。实际上,你也可以在Haskell中包含外部括号。所有其他Algol家族语言在函数名和参数之间引入括号和逗号。


1
Lisp源代码可以成为Lisp中的数据结构,因为Lisp是动态类型的,并且可以轻松处理包含符号、字符串、数字、向量、其他列表等混合元素的列表。 - Kaz

1

我想说这两种语言都是函数式编程语言,这使它们属于同一类别。但是我不会把Haskell称为Lisp的派生语言(像Scheme一样)。


1

可以说,所有函数式编程语言都是Scheme的后代,因为Scheme大致实现了lambda演算(虽然有些古怪),而函数式编程语言也实现了lambda演算,尽管它们不一定总是看起来像。同样可以说,ML的血统完全不同,因为它追溯到Landin的ISWIM,这对Lisp几乎没有影响,从一开始就知道它的理论基础。

真正的问题是Haskell和Lisp彼此比与C族或Prolog族中的任何一种更相似。

我本来会认为人们应该忽略语法问题,但我忘了Lispers把语法定义为成为lisp的一个关键部分。我觉得这很傻,因为按照这个标准,可以说Haskell不是Lisp,但Liskell是,尽管后者基本上只是前者的处理器。


5
“Scheme?不不不。Scheme是一些时髦的现代东西。当我们谈论函数式编程的基础时,我们要谈论早期原始的Lisp,即使“Lispers”今天也会看不起它。” - user395760
1
早期的原始Lisp尚未解决funargs问题,尽管大致同时期的工作已经解决了。没有适当的词法作用域和一级函数=远非功能完备。 - sclv
5
ML的渊源较为独特,因为它比Scheme更古老。Miranda渊源也是如此(SASL-KRC-Miranda-Haskell)。我想,Scheme的出版工作可以追溯到大约1976年,而SASL可以追溯到1972年。ML最初的主机LCF可以追溯到1972年,但我不知道它在其中的地位。Backus的FP甚至可能早于Scheme。 - stephen tetley
@delnan:Scheme语言的诞生可能比你还要早,除非你已经36岁或更年长。 - leppie
@sclv:Scheme共享ML语义,许多其他语言也是如此,例如OCaml、F#、SML甚至LISP-1。 - leppie
@leppi:没错。但是,第一个被称为Scheme的东西明显比麦卡锡最初的Lisp年轻得多。此外,“花哨的现代东西”听起来对你来说很严肃吗? - user395760

-2
Hoyte比较了一些编程语言,并声称Haskell不是Lisp,因为它在类型上过于严格,只适合学术界使用,而Common Lisp更像是一个原型语言(没有严格性,动态类型)。
参见:Doug Hoyte的《Let Over Lambda—50 Years of Lisp》(关于Common Lisp的高级书籍,http://letoverlambda.com/
Haskell和Common Lisp(可能所有的Lisp)都针对函数式编程(FP)范式进行了优化。 Haskell是纯的,而Common Lisp是不纯的。将术语FP与“total functional programming”进行对比。
还可以查看这个比较编程语言范式的图表:http://www.info.ucl.ac.be/~pvr/paradigms.html

2
Hoyte 对 Lisp 的看法通常被认为有些... 独特。 - sclv

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