Haskell的过去和现在

477 阅读21分钟

Haskell的过去和现在:采访Simon Peyton Jones

前段时间,我们得到了一个采访西蒙-佩顿-琼斯的绝佳机会,他是哈斯克尔设计的主要贡献者,也是格拉斯哥哈斯克尔编译器(GHC)的主要设计者之一。目前,西蒙在微软研究院工作,研究功能性编程语言。

在采访中,我们讨论了Haskell的过去、现在和未来,Haskell的好处和坏处,GHC,走在Haskell作为研究和工业语言之间的路线,以及其他多个话题。

以下是采访的一些要点,为清晰起见进行了编辑。

采访Simon Peyton Jones

从一个在编译器方面做了大量工作的人的角度来看,他长期以来做了大量的工作,使我们所有人都能享受到Haskell--我们拥有我们所知道和喜爱的Haskell是怎么发生的?

我的核心关注点,当然,我最初的唯一关注点是语言和它的编译器。但对于一种编程语言来说,要想成功地对任何人都有用,该语言和编译器必须存在于一个更大的工具和库的生态系统中。

最初,Haskell没有这些东西,所以当Cabal和Hackage出现时,就有了巨大的变化。在那之前,有一些Haskell的库,但没有好的包装和分发机制。所以Cabal和Hackage使Haskell生态系统发生了巨大的变化--他们使GHC和Haskell这种语言成为可能,并将其用于生产应用。我猜那是在21世纪初,类似的事情,然后就出现了一个巨大的增长库。

然后,我们看到了很多其他的东西:剖析和调试,以及最近,Haskell的IDE。所有这些都比编译器本身大得多,而且不是我的重点,但我很高兴它正在发生,而且我觉得它现在比过去发生得更好。

Haskell的生态系统部分是如何形成的?

好吧,请记住,Haskell社区已经有机地发展了30年。Haskell诞生于1990年,所以它是慢慢成长起来的,并不是突然诞生的。从大的方面来说,它只是在30年里成长了。

第二件要记住的事情是学者们没有企业赞助,你知道的。它不像C#,它诞生于微软。因此,Haskell在没有基本赞助商的情况下慢慢成长,这意味着社区以相当分散的方式成长。建立Cabal和Hackage的人与做GHC的人不同,他们与做Stack或IDE的人相当不同。

这是一种力量,对吧。多样性是好的,它意味着每个志愿者团体都有自主权,对他们所做的事情有一种代理感。但是,当然,Haskell对于更多的组织或人来说,任务越关键,它对这种相当松散的分布式组织的压力就越大。

举个语言本身的例子--在很长一段时间里,我们是如何将新功能引入语言的。好吧,基本上是西蒙-马洛和我,我们会想,你知道,"我们应该这样做",然后我们就把它放进去,它就在那里,在GHC中。或者一个实习生会来,在微软度过一个夏天,并会实现一些东西。

但随着这门语言对更多的人变得越来越重要,我们不得不越来越注意不要对人们造成干扰,而且说你在这门语言中获得某种东西的方法是通过了解西蒙,也变得不那么令人满意。部分原因是这显然太过精英化,但也因为它造成了太多的瓶颈。这导致了GHC的提议过程。当然,它也有缺点,但至少它意味着,如果你想把一些东西纳入语言,你可以写一个提案,让整个社区讨论,然后由一个委员会同意或不同意。这是我们逐步走向更透明的方式,(我非常希望)为更多人提供更多的声音。

有些人可能认为,提案过程降低了开发速度,甚至降低了一个功能最终进入编译器的可能性。你对此有什么评论?

这里有两件不同的事情要做。首先,一种语言和一个编译器之间存在着一种紧张关系,它是探索成为一个好的编程语言,特别是成为一个好的函数式编程语言的边缘的实验室。Haskell一直是一个这样的实验室--它探索了现在编程设计空间的一个特殊角落,也就是 "纯粹的函数式编程语言",并真正尝试投资于此。

作为一个实验室,一个可以插入许多想法的主板,与作为工业中关键任务应用的完全可靠的底板之间存在矛盾。

这是一种紧张关系,其他语言大多通过不做很大的改变来解决这个问题,但却偏向于后者--变得非常稳固和可靠,但却不能有很大的发展。目前,它的发展还是相当灵活的,你知道,我们有很多关于Dependent Haskell的讨论,线性类型最近也进入了,所以目前有很多事情在进行。

在某种程度上,我们通过在Haskell的用户中达成一种共识来驾驭这种紧张关系,即他们正在签署成为一个相当大的实验的一部分,而那些真正不希望这样的人可能不会使用Haskell。但与此同时,我们现在对回溯兼容性问题和迁移计划等给予了详尽的关注。我们对所有这些问题都比以前认真得多,但是,尽管如此,如果失去这些,我会感到非常遗憾。

还有第二个组成部分,就是我们同意我们继续前进--但我们如何继续前进?我们如何决定放什么?在语言中加入新东西的过程--这就是GHC的提议过程。首先要说的是。我认为这个过程常常被认为比它的实际情况更令人生畏或困难。它可能是缓慢的,它可能是缓慢的,有两个原因。第一是一个很好的原因,那就是有很多辩论,在我看来,通过这种辩论,提案有了很大的改善。在这个过程中,许多提案发生了非常重大的变化。我真的很喜欢这一点。这需要时间,如果你只是想 "我有一个好主意,我想做",花三个月的时间与社区讨论并看到它的改进,这是令人沮丧的。你甚至可能不认为它得到了改善,但不知何故,对它有了更大的共识。但我认为这基本上是一件好事。

第二件事不是那么好的事情,那就是委员会可能会很慢。为什么会这样呢?我们宣传说,一旦你作为一个提案的作者说--"请接受或拒绝或推回这个提案",那么事情就应该在一个月内发生。但它并不总是在一个月内发生。为什么会这样?

嗯,你知道,我和其他人一样有错。每个人都很忙,而且社区完全由志愿者组成,他们付出个人时间来详细考虑其他人突然提出的语言变化。

因此,这是他们给社区的一个相当大的礼物,我想向每个人道歉,对他们来说,这似乎是一个延迟。如果你认为你可以使之变得更好,请自愿参加--下次我们要求提名时,请提名你自己,我们需要那些愿意投入思考周期的人去做。

但有时提案,你知道,简单的提案--它们在几周内被提出并达成一致。这不是也不应该是那么可怕的,如果是这样,我感到很抱歉,如果有人因此而感到伤痛,可以来专门谈谈,谈谈这个过程,说我发现这有点困难,我们能做什么?

我们能不能从大局出发,谈一谈Haskell的最佳实践?正如你所说,Haskell语言随着时间的推移已经发生了巨大的变化。对Haskell的补充是什么,对你用Haskell编程的方式改变最大?

应该说,虽然Haskell这个源语言随着时间的推移发生了很大的变化,但Haskell这个核心语言,内部语言随着时间的推移变化很小。它仍然包含let、lambda、变量、常量、函数式应用,最大的变化是增加了casts和coercions,coercion抽象。现在,那是我们增加的一个大变化--小的内部语言有七个构造函数,现在有八个,或者类似的东西。

这确实是一个很小的变化。我的意思是,它有巨大的普遍性后果。我想说的是,在某种程度上,表面语言的变化是肤浅的。它们对你如何思考有深刻的影响,但它们都编入了这个相同的核心语言。因此,这意味着正在发生的一切都有一定的智力连贯性,它不是我们不断拍上的一个功能的布袋,尽管它有时可能感觉或看起来像这样。

回到你的问题,表面语言的哪些变化影响了我自己的编程实践--最近GHC中发生的最大的风格变化,我认为是朝着这个 "会生长的树 "的想法前进。现在,"生长的树",你可以在我的主页上搜索这个关键词作为关于它的论文,是一种使用Haskell制作可扩展数据类型的方式。这对Haskell的抽象语法树真的很有用。Haskell有一个非常大的具体语法,因此,相应地,也有一个大的抽象语法,也就是描述Haskell程序的内部数据类型,在你通过它们之后,有几十个数据类型和几百个构造函数,然后GHC在其重命名和类型检查阶段,用很多额外的东西装饰这个树:类型和作用域,以及各种额外的东西被添加到这个树上。所以,一开始,我们有一个只针对GHC的树,但后来我们越来越意识到,其他人也想为其他目的解析Haskell,所以我们真正想要的是一种基础库,它包含了核心的抽象语法树,有几十种数据类型和几百个构造函数,然后有一些方法让GHC定制这个树,添加所有的装饰品,这就是树的生长理念,它依靠类型族生存。我们广泛地使用了类型族和数据族来支持树的生长理念。这并不是类型族和数据族最初的目的,你可以把它们用于各种各样的事情,但这是GHC中的一个主要应用,它通过编译器推动了一种风格的改变。

如果你需要向初学者和刚刚开始写作的人解释,比如说工业Haskell,你会告诉他们什么是懒惰?

我会告诉他们去读John Hughes的论文"Why Functional Programming Matters",这篇论文非常清楚地阐述了懒惰是如何让你建立更多的模块化程序的。

也就是说,GHC的内部有很多东西是关于通过严格性分析来推断严格性的。另外,Haskell有很多注释,bang patterns和seq等等,让你强制编译器使用按值调用。所以中间语言,事实上,虽然它是一种懒惰的语言,但也有很多对按值调用机制的支持。所以,实际上,它不是懒惰的评估,它不是真正的非此即彼。每一种懒惰语言,嗯,当然是Haskell,都有很多对严格性的支持,而严格的函数式语言如ML或OCaml通常也有对懒惰的支持。

因此,这只是一个你从哪里开始的问题,我们现在有点向中间移动。理想情况下,我想你会喜欢一些光荣的统一,在其中你不必有一个默认值,但我目前不知道如何做到这一点。

人们经常说。"好吧,如果你再次设计Haskell,你会让它变得严格吗?"所以,首先,从历史上看,Haskell的决定性特征是它的纯粹和懒惰。而且,在某种程度上,它是无悔的纯粹,因为它是懒惰的。因为有了懒惰的评估,你就不知道什么时候会被评估,所以,如果它是不纯的,你有副作用,比如打开阀门或写两个变量,你就不知道这些事情什么时候会发生,如果你要打开阀门,你真的想知道你要先打开哪个阀门。

因此,一种不纯粹的懒惰语言似乎是不可行的。Haskell的懒惰使我们不可能考虑到不纯洁。现在,当然,我们仍然通过unsafePerformIO让它从后门进来,但它被称为unsafePerformIO是有原因的--我们甚至把它放在名字里。

回想起来,懒惰最有用的地方在于它迫使我们变得纯粹,这意味着Haskell最初甚至不能做输入/输出,因为输入/输出是不纯粹的,在适当的时候,这让我们看到了Phil Wadler的高明之处,即把[听不清]一直在写的关于单体的想法,在编程语言的非常实用的背景下应用它们。这导致了我们的论文 "强制性功能编程",这是一个突破性的时刻,我们说。"啊,现在我们可以看到如何在同一个程序中同时进行纯函数式编程和不纯函数式编程,而不被不纯所扰。那是一个惊人的、令人惊奇的时刻,如果我们不是因为懒惰而被迫进入这个纯粹的视野,它就不会发生,但现在它已经发生了,现在我们知道了纯粹性是多么重要,你能想象一种纯粹的严格语言,即使你知道评价顺序,你也不会向不纯粹性妥协吗?我曾经调侃说,你可以把语言重新设计成一种严格的语言,而且,我想,十年之后人们会说。"如果你重新设计Haskell,你会让它变得很懒吗?"是的,草总是在栅栏的另一边更绿,所以我对我们的选择很满意。

我非常坚信纯洁性是我们应该无悔地坚持的东西,但我对拥有一种纯洁的严格语言并对懒惰有真正好的支持的可能性非常开放。但我不想把Haskell转变为这种语言,因为这将是一个巨大的、破坏性的变化,而回报太少。

Haskell工程师是否需要有更深的数学背景,如果不需要,是否有什么地方需要有一些数学理论的背景?

我不确定你是否需要更深的数学背景,但我认为Haskell对数学也有吸引力的人有吸引力。它对一组类似的人有吸引力,所以我认为,除了每个程序员都需要的东西,比如推理,你并没有非常直接地使用数学。如果我要预测这个程序要做什么,或者思考它的结果,我需要以逻辑的方式推理,而且真的有一个答案,如果我把这个函数应用于这个参数,我就会得到这个结果。你可以把这称为计算思维,但你也可以把它称为数学思维,但如果你写的是Java,那也同样如此。

我认为因为Haskell函数默认是纯粹的,它们的行为就像数学函数一样,所以当你说 "f是一个使其参数平方的函数 "时,你从数学中得到的直觉--当你在数学中谈论一个函数时,总是暗示它是一个没有副作用的函数,当然,你调用它两次,它给出同样的答案,其他的都是愚蠢的--Haskell有点像与这些相同的直觉集合的裂缝,但我不认为你需要任何数学理解来理解这些。

然后你可能会想知道类别理论和漏斗和单体,等等。好吧,我最初并不了解任何范畴理论,即使现在,我也算是一个弱的范畴理论使用者,但可能我的大部分直觉来自于用漏斗和单体编程,而不是来自范畴理论本身。所以我认为你也不需要知道类别理论来编写Haskell程序。

我认为可能比对数学的感觉更重要的是,我认为--Haskell真正推动你的大事是认真对待类型,我的意思不仅仅是作为一个小的安全网来检查你是否在一个字符上添加了int。我的意思是,类型就像一个弱的定理。它是一个关于程序所做事情的真实陈述,你可以把函数定义看作是定理的证明。但是类型就是定理,随着时间的推移,你发现自己把越来越多的东西放到了类型中。

人们说,你知道,什么是相当于UML的Haskell,经过一段时间后,我意识到这就是类型。我们不需要一个单独的建模语言。当你开始写Haskell程序时,你做的第一件事就是开始为数据类型和类型或函数写类型声明,这是一种设计语言或建模语言,使你能够思考程序的主要部分,以及数据流,以及从这里到那里的内容。它不仅仅是一种独立的建模语言,它还成为你的程序中永远被机器检查的一部分。我认为,这种越来越多地涉及到类型的想法,对Haskell程序员来说,真的是无处不在,非常重要。

它在Haskell中比在其他静态类型的编程语言中更明显。我在这里说的不是Scala或OCaml,它们都在同一范围内,但与C或任何这些非类型化语言相比,这是一个相当大的文化转变。我认为它对数学家的吸引力可能又比对非数学家的吸引力大一些,但任何人都可以适应它。你不需要有数学背景就可以用Haskell编程。

你对计算的未来有什么看法?你认为我们在计算机运行代码的方式上会有大的突破吗?例如,有一些关于可逆计算和量子计算以及诸如此类的研究。你能谈谈这个吗?

在20世纪80年代,当我在剑桥大学攻读计算机科学文凭时,围绕着设计硬件来直接执行功能程序的想法,有很多人都很兴奋。事实上,当时有一个名为 "功能编程和计算机结构"(FPCA)的会议。我的一些第一篇论文就是在FPCA上发表的。后来,它和里斯本功能编程会议合并了,它们都是每两年举行一次,所以它们合并成了ICFP--国际功能编程会议。

但它非常有趣,它的标题是 "函数式编程和计算机体系结构"。这难道不是一个惊人的想法吗?但随着时间的推移,我想大家都明白了,首先,要和英特尔竞争真的很难,它需要巨大的投资来制造硬件芯片,所以很难竞争,而且,当你有一个非常好的编译器时,你不想做的是制造硬件,在运行时解释你可以事先静态编译的东西。那就太傻了,那只是在一次投入周期来做一些你可以直接*[挥手*]的事情。

而这正是GHC花费大量时间做的事情,我们花了相当长的时间来弄清楚这一切,我们为此写了一整本书。我可以看到有些事情我们可以做一些额外的硬件支持,特别是,更好地支持[听不清]和[听不清]的垃圾收集器,不要避免为你知道是空的堆单元获取缓存行。我认为有一些适度的硬件支持可以帮助,我不知道它是否会改变。

量子计算可能会改变世界,但我不认为它会这么快;它总是10或15年后,我不认为我们会用量子计算编写Word程序。它可能会开始变得直接有用,但我认为它可能是在相当专业的应用中。 我真的不知道,但它有点像核聚变,我认为它可能总是有点在地平线上。但因为它将是变革性的,我认为它值得投资,我只是没有屏住呼吸。

我认为,从硬件的角度来看,我们大多数人不太可能很快发生很多变化,我认为目前对我们来说,最大的变化是机器学习/人工智能的事情。

现在,我知道这是很有味道的,而且充满了炒作,但事实是,多年来,你知道,在我的整个职业生涯中,直到最近,我认为你让计算机做你想做的事情的方法是一步一步地告诉它,或者也许像哈斯克尔语那样声明性地告诉它到底该怎么做。现在,机器学习完全是围绕着这整个事情进行的。如果有人说,告诉我一步一步地用Haskell程序来识别一只猫,以我们认为编写算法程序的方式,这真的很难直接做到,但机器学习程序却很擅长这样做。嗯,这个程序相当简单,只有几十行或几百行代码,仍然是一个程序,当然,仍然是在同样的老硬件上执行,也许有一点专门的硬件支持。但作为一种告诉计算机你想做什么的方法,它是完全不同的。函数式编程是不同的,与命令式编程非常不同,但如果你放大一点,那么你知道机器学习又是非常非常不同的。

我认为这将会使很多东西发生变化。我们需要仔细思考这个问题。我确实认为Haskell可以成为描述机器学习模型的一种非常好的语言,在机器学习领域有大量的实验,所以有一种语言可以很容易地移动和探索,并改变事情,这将是非常好的,有一些Haskell库围绕着这一点。

因此,我认为就计算的未来的重大影响而言:抛开炒作,我确实认为整个机器学习的事情会有一个缓慢的地震影响。它不会消失,它将有一个长期的影响。我不认为它会直接影响函数式编程,但它会直接影响计算机,会直接影响计算机科学的大方向。

但我仍然认为,函数式编程正走在这条长征路上。要说,如果你想用算法的方式写程序,"A计划','就像它一样,那么我认为随着时间的推移,函数式编程将增加它的稳定增长,事实上,越来越多地感染主流世界。我经常说,当命令式编程的石灰石被磨掉后,下面就会露出函数式编程的花岗岩。我仍然这样认为,所以我认为那里也有一个长期的趋势。