Haskell之后要学习什么语言?[关闭]


85

作为我的第一门编程语言,我决定学习Haskell。我是分析哲学专业的学生,​​Haskell允许我快速而正确地创建感兴趣的程序,例如,用于自然语言解析的转换器,定理证明和解释器。尽管我只从事了两个半月的编程,但我发现Haskell的语义和语法比更传统的命令式语言更容易学习,并且对大多数构造感到满意(现在)。

但是,在Haskell中进行编程就像是巫术,我想扩展我的编程知识。我想选择一种新的编程语言来学习,但是我没有足够的时间来挑选一种任意的语言,删除它并重复。所以我想在这里提出这个问题,以及关于我要寻找的语言类型的一些规定。有些是主观的,有些是为了简化从Haskell的过渡。

  • 强类型系统。在Haskell中,我最喜欢的编程部分之一是编写类型声明。这有助于构造我对单个功能及其与程序整体关系的思想。这也使非正式的推理程序变得更加容易。我关注的是正确性,而不是效率。
  • 强调递归而不是迭代。我在Haskell中使用了迭代构造,但是递归地实现了它们。但是,与复杂的迭代过程相比,了解递归函数的结构要容易得多,尤其是在使用组合器和高阶函数(例如图,折叠和绑定)时。
  • 奖励学习。Haskell是一种有用的工作语言。这有点像阅读Kant。但是,几年前我没有使用C的经验。我不是在寻找C。这种语言应该执行一种概念上有趣的范式,就我完全主观的观点而言,C语言不是。

权衡答案:当然,这些只是笔记。我只想回复所有给出正确答案的人。您一直很有帮助。

1)若干答复表明,强调递归的强大的静态类型语言意味着另一种功能语言。尽管我想继续与Haskell进行紧密合作,但是camccann和larsmans正确地指出,另一种这样的语言会“过度简化过渡”。这些评论非常有帮助,因为我不想用Caml写Haskell!在证明助手中,Coq和Agda都很有趣。特别是,Coq将为构造逻辑和形式类型理论提供扎实的介绍。我花了一会儿时间来研究一阶谓词和模态逻辑(Mendellsohn,Enderton和某些Hinman),所以我可能会对Coq感到很多乐趣。

2)其他人则非常喜欢Lisp(通用Lisp,Scheme和Clojure)。据我了解,Common Lisp和Scheme都有出色的入门资料(关于LispThe Reasoned SchemerSICP)。SICP中的材料使我倾向于使用Scheme。特别是,通过SICP进行的计划将涵盖不同的评估策略,懒惰的实现,并有机会关注诸如延续,解释器,符号计算等主题。最后,正如其他人指出的那样,Lisp对代码/数据的处理将是全新的。因此,我非常倾向于选项(2),即Lisp。

3)第三,序言。Prolog有很多有趣的材料,它的主要领域正是我感兴趣的领域。它的语法简单,易于阅读。目前,我无法发表更多评论,但是在阅读了Prolog的概述并浏览了一些入门资料之后,它的排名为(2)。看来,Prolog的回溯一直被黑客入侵Haskell!

4)在主流语言中,Python看起来最有趣。蒂姆·耶茨(Tim Yates)使这些语言听起来很吸引人。显然,Python通常是针对一年级CS专业的学生而教。因此它在概念上丰富或易于学习。我必须做更多的研究。

谢谢大家的建议!看起来像Lisp(方案,Clojure),Prolog或像Coq或Agda这样的证明助手是推荐的主要语言。


34
2.5个月的时间不足以深入学习任何一种语言,很抱歉打破您的泡沫。
Woot4Moo

20
确实是这样。我并不是要暗示我会“学习” Haskell,无论这意味着什么。我的意思是说我使用该语言感到很自在。我显然不会“停止学习”它。
danportin 2010年

10
@Michael:我希望看到更多有关编码而不是效率的信息
Deniz Dogan 2010年

24
@ Woot4Moo:但是,花2.5个月的时间足以让一种语言“感到舒适”。如果他熟悉形式逻辑并使用他的哲学背景的抽象概念,那么无疑。在这种情况下,不必从其他语言中学习习惯也将有所帮助。
CA McCann 2010年

8
@gnovice:肯定已经问过很多次了。但这是我第一次遇到曾在Haskell进行过第一次严肃编程经验的人。就像时间的箭头已经倒转一样。
Muhammad Alkarouri

Answers:


85

我想拓宽我的编程知识。(...)我以为我会在这里提出问题,以及关于我要寻找的语言类型的一些规定。有些是主观的,有些是为了简化从Haskell的过渡。

强类型系统。(...)这也使非正式的推理程序变得更加容易。我关注的是正确性,而不是效率。

强调递归而不是迭代。(...)

恐怕您在这里可能会过分放松过渡。Haskell的特征是非常严格的类型系统和纯函数式风格,几乎任何类似于主流编程语言的东西都需要至少在其中之一上做出妥协。因此,考虑到这一点,这里是旨在保留了一些广泛的建议大部分的你似乎什么喜欢哈斯克尔,但也有一些重大的转变。

  • 忽略实用性,追求“ Haskell比Haskell更多”:由于未终止和其他混乱的折衷,Haskell的类型系统充满了漏洞。清理混乱并添加更强大的功能,您将获得CoqAgda之类的语言,其中函数的类型包含其正确性的证明(您甚至可以将函数箭头->视为逻辑含义!)。这些语言已用于数学证明和具有极高正确性要求的程序。Coq可能是该样式中最突出的语言,但是Agda更具Haskell-y的感觉(以及用Haskell本身编写)。

  • 忽略类型,添加更多的魔术:如果Haskell是巫术,那么Lisp是原始的原始魔术。Lisp族语言(还包括SchemeClojure)具有几乎无与伦比的灵活性以及极简主义。这些语言基本上没有语法,直接以树数据结构的形式编写代码。Lisp中的元编程比某些语言中的非元编程更容易。

  • 妥协了一下,靠拢主流:哈斯克尔落入由ML严重影响语言,其中的任何一个你很可能转移到没有广泛的家庭太多太多的困难。从功能样式的类型和使用方面,Haskell是最严格的保证之一,其中其他形式通常是混合样式,并且/或者出于各种原因做出实用的折衷。如果您想接触OOP并访问许多主流技术平台,请使用JVM上的ScalaF#.NET上的Haskell与Haskell有很多共同点,同时提供了与Java和.NET平台的轻松互操作性。Microsoft直接支持F#,但是与Haskell和非Windows平台上的可移植性问题相比,F#具有一些令人讨厌的限制。Scala与Haskell的类型系统和Java的跨平台潜力有着直接的对等关系,但是Scala具有更重的语法,并且缺少F#所拥有的强大的第一方支持。

其他建议中也提到了大多数建议,但是希望我的建议能够为您提供一些启发。


4
CoqAgda的家庭中,您也可以查看Qi II
海尼克

您认为F#的恼人限制是什么?作为在业余时间学习F#的人,我很好奇。
卢卡斯

7
@Lucas:与Haskell相比,Haskell的最大缺点是缺乏更高种类的多态性和类型类。除此之外,许多GHC特定的扩展都非常不错。无论如何,这都不是致命的缺陷,但是在习惯了Haskell之后,没有那种东西感觉有点笨拙。想象一下从现代C#回到使用C#1.x ...
CA McCann 2010年

@HyneK:乍一看,这种Qi 2语言似乎比Coq或Adga都非常有趣并且更加灵活。看来尽管作者决定退出它。有什么动静继续使用这种语言吗?我不想学习已经死了一半的东西。
亚历克斯(Alex)2010年

@Alex:看起来像神一样继续:shenlanguage.org
amindfv 2013年

20

我将成为那个家伙,建议您要问错的事情。

首先,您说您想开阔眼界。然后,您描述所需的语言,它的视野听起来像您已经拥有的视野。一遍又一遍地学习相同的东西,您不会收获太多。

我建议您学习Lisp,即Common Lisp,Scheme / Racket或Clojure。默认情况下,它们都是动态输入的,但是具有某种类型的提示或可选的静态输入。球拍和Clojure可能是您最好的选择。

Clojure是较新的,具有更多的Haskellism,例如默认情况下具有不变性和许多惰性评估,但是它基于Java虚拟机,这意味着它有一些奇怪的缺点(例如JVM不支持尾调用消除,因此递归是一种hack)。

Racket的年龄要大得多,但是在此过程中已经获得了很多功能,例如静态类型支持和对函数式编程的关注。我认为您可能会充分利用Racket。

Lisps中的宏系统非常有趣,并且比您在其他任何地方都能看到的任何功能强大得多。至少值得一看。


3
呵呵,从Haskell的角度来看,类型提示或可选的静态类型与完全动态类型看起来并没有什么不同。这是非常不同的心态。就是说,Lisp-y语言非常有趣,我认为每个程序员都应该至少花一些时间来学习。
CA McCann

19

从适合您的专业的角度来看,显而易见的选择似乎是一种逻辑语言,例如Prolog或其派生词。逻辑编程可以用一种功能语言(例如参见The Reasoned Schemer)非常整齐地完成,但是您可能会喜欢直接使用逻辑范例。

交互式定理证明系统,例如twelf或coq,也可能会引起您的注意。


2
当您对强类型语言感兴趣时,我建议使用lambdaProlog,这是一种类型化的高阶逻辑编程语言。一个编制实施是Teyjus - code.google.com/p/teyjus(披露:我的工作Teyjus)。
Zach Snow

18

我建议您学习Coq,它是一个功能强大的证明助手,其语法对Haskell程序员来说很舒服。关于Coq的很酷的事情是它可以提取到其他功能语言,包括Haskell。甚至还有一个用Coq编写的关于Hackage的软件包(Meldable-Heap),它具有经过验证的操作性能,然后提取到Haskell。

另一种比Haskell更具功能的流行语言是Agda-我不知道Agda是依赖于依赖于Hacked的类型输入的,并且得到了我尊敬的人的尊重,但这对我来说是足够的理由。

我不希望这些都容易。但是,如果您了解Haskell,并想发展一种比Haskell类型系统功能强大的语言,那么应该考虑使用它们。


1
Agda听起来确实像Haskell的自然“下一步”。
Deniz Dogan 2010年

5
还要注意的是,如果作为哲学专业的他在形式逻辑方面具有丰富的经验,那么Curry-Howard风格的证明助手对他的困扰可能不如大多数资深程序员那么大!
CA McCann 2010年

11

由于除了主观兴趣之外,您没有提到任何限制,而是强调“奖励学习”(好的,我将忽略静态类型限制),所以我建议您学习几种不同范式的语言,最好学习是每个人的“典范”。

  • 一种Lisp方言,用于作为数据编码/纯文本的事物,并且因为它们是动态的(或多或少严格的)功能编程语言的好(如果不是最好的话)示例
  • Prolog作为主要的逻辑编程语言
  • Smalltalk是一种真正的OOP语言(由于它通常以图像为中心,因此也很有趣)
  • 如果您对为并行/并行/分布式编程伪造的语言感兴趣,则可能是ErlangClojure
  • 面向堆栈编程的第四
  • Haskell用于严格的功能静态类型的惰性编程)

特别是Lisps(CL不如Scheme)和Prolog(和Haskell)都采用了递归。

尽管我不是任何一种语言的专家,但我确实与每种语言都花了一些时间,但Erlang和Forth除外,它们都给了我大开眼界和有趣的学习经验,因为每种语言都以不同的角度来解决问题。 。

因此,尽管似乎我似乎忽略了您没有时间尝试几种语言的部分,但我认为不会浪费任何时间花费在这些语言上的时间,而您应该仔细研究所有这些语言。


我不能忍受Erlang对监护人的限制;)
gorsky

10

怎么样面向堆栈的编程语言命中你的高点。它是:

  • 带有类型推断的静态类型。
  • 使您重新考虑常见的命令式语言概念,例如循环。条件执行和循环由组合器处理。
  • 奖励-迫使您了解另一种计算模型。为您提供了另一种思考和分解问题的方式。

Dobbs博士在2008年发表了一篇有关Cat的简短文章,尽管该语言略有变化。


10

如果您想输入更强大的Prolog,Mercury是一个有趣的选择。我过去涉猎其中,我喜欢它给我的不同观点。在类型系统中,它还具有适度性(需要自由/固定哪些参数)和确定性(有多少结果?)。

Clean与Haskell非常相似,但是具有唯一性键入,它可以用作Monad(更确切地说是IO monad)的替代。唯一性键入对于处理数组也有有趣的作用。



8

尽管它无法满足您的一项重要标准(静态*类型),但我还是为Python提供了理由。我认为您应该看一下以下几个原因:

  • 对于命令式语言,它具有令人惊讶的功能。这是我学到的东西之一。以列表理解为例。它具有lambda,一流的功能,并且在迭代器(地图,折叠,拉链等)上具有许多受功能启发的组合。它使您可以选择最适合问题的范式。
  • 恕我直言,就像Haskell一样,它的代码漂亮。语法简单而优雅。
  • 它的文化专注于以简单的方式做事,而不是过于专注于效率。

我了解您是否正在寻找其他东西。例如,正如其他人所建议的那样,逻辑编程可能就在您的小巷。


*我假设您的意思是静态类型,因为您要声明类型。从技术上讲,Python一种强类型语言,因为您不能随意将字符串解释为数字。有趣的是,有一些Python派生类支持静态类型,例如Boo


强类型系统不一定只意味着“静态”类型。
Deniz Dogan 2010年

+1也可以看到我对larsmans的回答的评论。但是要小心地宣传Python的功能。例如,生成器表达式通常优于mapfilter等等。但是,对于那些知道惰性求值和所述函数的人来说,生成器和生成器表达式仍会很熟悉。

16
真?我认为Python对那些没有做太多功能编程的人来说似乎特别有用。我已经大量使用了Python和Haskell,虽然Python是一门不错的语言,并且确实从功能语言中借鉴了一些东西,但仍然有99%的必要性。
CA McCann 2010年

@camccann你是对的-我的观点是不同的,这就是为什么我只是将其作为一种有趣的选择提供。作为一个首先学习命令式编程的人,我很欣赏Python让我在适当的地方使用功能性技术,而在其他有意义的地方避免使用它们。我并没有说它“可以”起作用-只是说它做出了很好的妥协。
蒂姆·耶茨

从Haskell中学到的习惯可以使您成为比以第一语言学习它的其他人更好的Python程序员。
u0b34a0f6ae

8

我会推荐您Erlang。它不是强类型的语言,您应该尝试一下。这是非常不同的编程方法,您可能会发现强类型不是The Best Tool(TM)的问题。无论如何,Erlang为您提供了用于静态类型验证的工具(打字机,透析仪),并且您可以在从中受益的零件上使用强类型打字。对您来说这可能是有趣的经历,但要做好准备,那将是完全不同的感觉。如果您正在寻找“概念上有趣的范例”,则可以在Erlang中找到它们,消息传递,内存分离而不是共享,分发,OTP,错误处理和错误传播,而不是错误“预防”等等。Erlang可能会与您目前的经验相去甚远,但是如果您有使用C和Haskell的经验,仍然会感到挠痒。


8

根据您的描述,我建议使用OcamlF#

就强大的类型系统而言,ML系列通常非常出色。递归与模式匹配的结合也很明显。

我有些犹豫的地方是学习收获。毫无疑问,学习它们对我来说是有益的。但是,鉴于您的限制和对所需内容的描述,看来您实际上并没有在寻找与Haskell不同的东西。

如果您不加限制,我会建议使用PythonErlang,这两种方法都会使您脱离舒适度。


6

以我的经验,强类型输入+强调递归意味着另一种功能编程语言。再说一次,我想知道这是否很有意义,因为它们都不像Haskell那样“纯粹”。

正如其他张贴者所建议的那样,即使Prolog和Lisp / Scheme都是动态键入的,它们也不错。尤其是有关Scheme的许多书籍都具有很强的理论“品味”。看一下SICP,它也传达了许多通用的计算机科学知识(元循环解释器等)。


4
+1为第一段,正好是我阅读问题时的想法。为了学习新事物,我建议使用现代命令式语言,例如Python-尤其是因为它不是OP所习惯的(动态类型,无处不在的迭代器等)。它还具有非常酷的高级概念,例如元类或生成器(与惰性列表非常相似)/生成器表达式(用作列表推导+生成器的泛化)。同样,命令并设置理解规则。

3
@delnan:Haskell也具有列表理解能力,并且可以使用Haskell的标准列表类型在Haskell中轻松表达生成器/迭代器。因此,我认为这两种语言之间的最大差异将是面向对象的编程和(最常见的)不纯数据结构(例如字典)。
Deniz Dogan 2010年

1
@Deniz Dogan:不要忘记Python中缺少声明和适当的词法作用域。
Fred Foo 2010年


5

您可以开始研究Lisp

Prolog也是一种很酷的语言。


5

如果您决定不喜欢类型系统,那么您可能会对J编程语言感兴趣。它以强调功能组成而著称。如果您喜欢Haskell中的无点样式,则J的默认形式将很有意义。我发现它异常发人深省,尤其是在语义方面。

是的,这不符合您对所需内容的先入之见,但请看一下。仅仅知道它在那里是值得发现的。完整实现的唯一来源是J Software,jsoftware.com。


0

与主流之一一起去。考虑到可用资源,您技能的未来可销售性,丰富的开发人员生态系统,我认为您应该从JavaC#开始


14
与Haskell相比,这两种语言都是相当la脚的IMO。
missingfaktor 2010年

9
让Haskeller迁移到Java就像让Bill Gates迁移到贫民窟。:-/
missingfaktor

1
+1提出一些肯定会让您失望的建议。Java和C#具有良好的生态系统,因此非常推荐它们用于认真的工作。一定要在JVM上使用Clojure或在CLR上使用F#时,才能充分利用Haskell(Java和C#)的知识。
ponzao 2010年

6
@ponzao:Urgh,不,这表明有人从Haskell转到Java或C#简直是可怕而残酷。Scala中,F#和Clojure的有很多更好的语言与所有来自于JVM / CLR上运行同样的好处。
CA McCann

5
对于分析哲学而言,主要的Java或C#浪费时间。
MaD70

0

很好的问题-我花了几个月的时间完全享受了Haskell之后,最近才问自己,尽管我的背景非常不同(有机化学)。

像您一样,C及其同类也不在话下。

我一直在Python和Ruby之间摇摆,这是今天的两种实用的主力脚本语言(mules?),它们都具有一些使我感到高兴的功能组件。在这里没有开始任何Rubyist / Pythonist辩论,但是我个人对这个问题的务实回答是:

学习一个您首先获得借口的应用程序(Python或Ruby)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.