What language to learn after Haskell?
作为我的第一种编程语言,我决定学习haskell。我是分析哲学专业的学生,Haskell允许我快速正确地创建感兴趣的程序,例如,自然语言分析的传感器、定理证明者和解释者。虽然我只进行了两个半月的编程,但我发现haskell的语义和语法比更传统的命令式语言更容易学习,并且对它的大多数结构感到舒适(现在)。
不过,哈斯克尔的编程就像魔法,我想拓宽我的编程知识。我想选择一种新的编程语言来学习,但是我没有足够的时间来学习一种任意语言,放弃它,然后重复。所以我想我会在这里提出这个问题,以及一些关于我正在寻找的语言类型的规定。有些是主观的,有些是为了缓解哈斯克尔的转变。
- 强类型系统。Haskell中我最喜欢的编程部分之一是编写类型声明。这有助于构建我对单个函数及其与整个程序的关系的想法。它还使非正式地推理程序的正确性变得更容易。我关心的是正确性,而不是效率。
- 强调递归而不是迭代。我在haskell中使用迭代构造,但是递归地实现它们。然而,与复杂的迭代过程相比,更容易理解递归函数的结构,尤其是在使用组合器和高阶函数(如映射、折叠和绑定)时。
- 值得学习。哈斯克尔是一种值得学习的语言。这有点像读康德。然而,几年前我在C公司的经历并不是这样的。我不是在寻找C语言。语言应该执行一个概念上有趣的范例,在我完全主观的观点中,C语言喜欢的人不会。
权衡答案:当然,这些只是笔记。我只想回答所有做出正确回答的人。你帮了很大的忙。
1)一些回答表明,强调递归的强静态类型语言意味着另一种功能语言。虽然我想继续与哈斯克尔密切合作,但卡曼和拉斯曼正确地指出,另一种语言将"过度缓和过渡"。这些评论非常有帮助,因为我不想写哈斯克尔在卡姆!在证据助理中,COQ和AGDA看起来都很有趣。特别是,COQ将为构造逻辑和形式类型理论提供坚实的介绍。我花了一点时间研究一阶谓词和模态逻辑(门德尔松,恩德斯顿,一些希曼),所以我可能会对coq有很多乐趣。
2)其他严重支持Lisp(常见Lisp、Scheme和Clojure)。据我所知,常见的Lisp和Scheme都有很好的介绍材料(关于Lisp和理性的Schemer,Sicp)。SICP中的材料使我倾向于计划。特别是,通过SICP的方案将涵盖不同的评估策略、惰性的实现,以及关注延续、解释、符号计算等主题的机会。最后,正如其他人指出的,Lisp对代码/数据的处理将是全新的。因此,我倾向于选择(2),一个口齿不清。
3)第三,序言。Prolog有大量有趣的资料,它的主要领域正是我感兴趣的领域。它语法简单,易于阅读。目前我不能多加评论,但在阅读了Prolog的概述和略读了一些介绍性材料之后,它排在第(2)位。似乎普罗洛格的回溯总是被黑客入侵哈斯克尔!
4)在主流语言中,Python看起来最有趣。提姆·耶茨使这些语言听起来很有吸引力。显然,Python经常被教授给一年级的CS专业学生;所以它要么概念丰富,要么易于学习。我得做更多的研究。
谢谢大家的推荐!它看起来像一个Lisp(Scheme,Clojure),Prolog,或者像Coq或Agda这样的证据助理是被推荐的主要语言。
I would like to broaden my knowledge of programming. (...) I thought I would pose the question here, along with several stipulations about the type of language I am looking for. Some are subjective, some are intended to ease the transition from Haskell.
Strong type system. (...) It also makes informally reasoning about the correctness of my program easier. I'm concerned with correctness, not efficiency.
Emphasis on recursion rather than iteration. (...)
恐怕你在这里缓和的过渡有点过分了。非常严格的类型系统和纯粹的功能风格是haskell的特点,几乎任何类似于主流编程语言的东西都需要在其中一个方面有所妥协。因此,考虑到这一点,这里有一些广泛的建议,旨在保留大部分你似乎喜欢的关于哈斯克尔,但有一些重大的转变。
忽视实用性,去追求"更多的哈斯克尔比哈斯克尔":哈斯克尔的类型系统是充满漏洞,由于不终止和其他混乱的妥协。清理混乱,添加更强大的功能,您可以使用诸如coq和agda之类的语言,其中函数的类型包含其正确性的证明(您甚至可以将函数arrow
-> 作为逻辑含义读取!)这些语言已经用于数学证明和具有极高正确性要求的程序。coq可能是最突出的风格语言,但agda有一个更哈斯克尔Y的感觉(以及被写在哈斯克尔本身)。忽视类型,增加更多的魔法:如果哈斯克尔是巫术,Lisp是原始的,原始的创造魔法。Lisp家族语言(也包括Scheme和Clojure)具有几乎无与伦比的灵活性,并结合了极简主义。语言基本上没有语法,直接以树数据结构的形式编写代码;在Lisp中的元编程比在某些语言中的非元编程更容易。
妥协一点,然后向主流靠拢:haskell属于受ML影响很大的广泛语言家族,任何一种语言都可以在不太困难的情况下转换。当涉及到类型和功能样式的使用的正确性保证时,haskell是最严格的保证之一,其中其他的通常是混合样式和/或出于各种原因做出务实的妥协。如果您想接触OOP并访问许多主流技术平台,JVM上的斯卡拉或者F.O.O.NET与Haskell有很多相同之处,同时提供与Java和.NET平台的简单互操作性。F由微软直接支持,但与haskell和非Windows平台上的可移植性问题相比,它有一些恼人的限制。Scala与Haskell的类型系统和Java的跨平台潜力有着直接的对应关系,但是它具有更重的语法,而缺少FF喜欢的强大的第一方支持。
这些建议中的大多数也在其他答案中提到,但希望我的理论基础能够提供一些启示。
我会成为那个人,建议你找错了。
首先你说你想开阔你的视野。然后你描述你想要的语言类型,它的视界听起来非常像你已经拥有的视界。一次又一次地学习同样的东西,你不会得到很多。
我建议你学习口齿不清-即普通口齿不清,诡计/球拍或Clojure。默认情况下,它们都是动态类型,但具有某种类型提示或可选静态类型。球拍和Clojure可能是你最好的赌注。
CuljuleReJuje是最新的,它有更多的Haskelistic,比如默认的不可更改性和很多懒惰的评估,但是它基于Java虚拟机,这意味着它有一些奇怪的疣(例如JVM不支持尾部调用消除,所以递归是一种黑客攻击)。
球拍更老了,但一路上已经积累了很多力量,比如静态类型支持和功能编程。我想你可能会从球拍中得到最大的收获。
Lisp中的宏系统非常有趣,而且比您在其他地方看到的任何系统都强大。这一点至少值得一看。
从适合你专业的角度来看,显而易见的选择似乎是一种逻辑语言,如prolog或其派生语言。逻辑编程可以用一种功能语言非常巧妙地完成(参见,例如推理的Schemer),但是您可能喜欢直接使用逻辑范式。
一个交互式的定理证明系统,如twelf或coq,也可能会引起你的兴趣。
我建议你学习coq,它是一个强大的语法校对助手,对haskell程序员来说会感到很舒服。coq最酷的地方是它可以被提取到其他的功能语言,包括haskell。甚至还有一个包(可合并堆)在hackage上,它是用coq编写的,具有证明其操作的属性,然后提取到haskell。
另一种比haskell更强大的流行语言是agda——我不知道agda,除了知道它是依赖于打字、被黑客攻击以及被我尊敬的人所尊重之外,这些对我来说都是很好的理由。
我不希望这两件事都简单。但是,如果你知道haskell,并且想继续使用一种比haskell类型系统更强大的语言,那么应该考虑它们。
因为除了你的主观兴趣之外,你没有提到任何限制,并且强调"值得学习"(好吧,好吧,我会忽略静态类型限制),所以我建议学习几种不同范例的语言,最好是那些对每种语言都是"示范性"的语言。
- 一种lisp方言,用于将代码作为数据/同象性的东西,因为它们是动态(或多或少严格)函数式编程语言的好例子(如果不是最好的话)。
- prolog作为主要的逻辑编程语言
- smalltalk作为一种真正的OOP语言(也很有趣,因为它通常以图像为中心的方法)
- 如果您对为并发/并行/分布式编程而伪造的语言感兴趣,可以使用erlang或clojure。
- 面向堆栈编程
- (Haskell用于严格的函数静态类型的惰性编程)
尤其是lisps(cl不如scheme)和prolog(和haskell)接受递归。
虽然我不是这些语言中的任何一种大师,但我确实花了一些时间和他们每一个人在一起,除了二郎和其他,他们都给了我开阔的视野和有趣的学习经验,因为每个人都从不同的角度来解决问题。
所以,尽管我似乎忽视了你没有时间尝试几种语言的部分,但我更愿意认为花在这些语言上的时间不会浪费,你应该看看所有的语言。
如果您想要一个强(ER)类型的prolog,Mercury是一个有趣的选择。我过去曾涉猎过它,我喜欢它给我的不同视角。它还具有适度性(哪些参数需要是自由/固定的)和确定性(有多少个结果?)在类型系统中。
clean与haskell非常相似,但具有唯一性类型,用作monad(更具体地说,io monad)的替代。唯一性类型对于使用数组也很有意思。
一种面向堆栈的编程语言怎么样?猫达到你的最高点。它是:
- 静态类型化,带有类型推断。
- 使您重新思考常见的命令式语言概念,如循环。条件执行和循环是用组合器处理的。
- 奖励-迫使你理解另一个计算模型。给你另一种思考和分解问题的方法。
多布斯博士在2008年发表了一篇关于猫的短文,尽管语言略有变化。
我有点晚了,但是我发现没有人提到过一些范例和相关的语言,这些范例和语言可以让您对它们的抽象性和一般性产生兴趣:
- 重写系统,如Maude或Elan;
- 约束处理规则(CHR)。
根据您的描述,我建议您使用OCAML或F。
就强类型系统而言,ML系列通常非常好。对递归的强调,加上模式匹配,也很明显。
我有点犹豫不决的地方是学习的回报。毫无疑问,学习它们对我来说是一种回报。但是考虑到你的限制和对你想要的东西的描述,你似乎并没有在寻找比哈斯克尔更不同的东西。
如果你不加以限制,我会建议你使用python或erlang,这两种方法都会让你脱离舒适区。
尽管它未能满足您的一个重要标准(静态*键入),但我将为Python做一个案例。我认为您应该看看以下几个原因:
- 对于命令式语言,它的功能令人惊讶。这是我学到的东西之一。以列表理解为例。它有lambda、一流的函数,以及迭代器(map、folds、zips…)上许多功能性启发的组合。它让您可以选择最适合问题的模式。
- 嗯,就像哈斯克尔一样,编码很漂亮。语法简单而优雅。
- 它有一种文化,专注于以直截了当的方式做事,而不是过于注重效率。
不过,我知道如果你在找别的东西。例如,正如其他人所建议的,逻辑编程可能就在你的道路上。
*我假设您在这里是指静态类型,因为您想要声明这些类型。从技术上讲,python是一种强类型语言,因为您不能随意地将字符串解释为数字。有趣的是,还有允许静态类型的Python派生,比如boo。
我推荐你二郎。它不是强类型语言,您应该尝试它。它是一种非常不同的编程方法,您可能会发现在某些问题上,强类型不是最好的工具(tm)。无论如何,Erlang为您提供了静态类型验证工具(typer、dialyzer),您可以在从中获益的部分使用强类型。这对你来说可能是一次有趣的经历,但要做好准备,感觉会大不一样。如果您在寻找"概念上有趣的范例",您可以在Erlang、消息传递、内存分离(而不是共享)、分发、OTP、错误处理和错误传播(而不是错误"预防")中找到它们。二郎可能远离你目前的经验,但如果你有经验与C和哈斯克尔仍然头脑发痒。
因素将是一个很好的选择。
根据我的经验,强类型+强调递归意味着另一种函数式编程语言。再说一次,我想知道这是不是很有回报,因为没有一个会像哈斯克尔那样"纯洁"。
正如其他海报所建议的那样,prolog和lisp/scheme是不错的,尽管它们都是动态类型的。许多对他们有强烈理论"品味"的伟大著作,特别是关于计划的出版。看看sicp,它也传达了很多普通的计算机科学智慧(元循环解释器等)。
如果您决定放弃对类型系统的偏好,您可能会对J编程语言感兴趣。它突出强调功能组合。如果你喜欢哈斯克尔的无点风格,J的默契形式将是值得的。我发现它非常发人深省,尤其是在语义方面。
是的,这不符合你对你想要什么的成见,但是看看吧。只知道它在外面是值得发现的。完整实现的唯一来源是j software.com。
你可以开始研究Lisp。
prolog也是一种很酷的语言。
很好的问题——我最近一直在问自己,虽然我的背景非常不同(有机化学)。
像你一样,C和它的同类是不可能的。
我一直在python和ruby之间摇摆不定,它们是当今两种实用的Workhorse脚本语言(mules?)它们都有一些功能组件来让我开心。这里没有任何关于鲁比派/皮托派的辩论,但我个人对这个问题的务实回答是:
学习第一个得到应用借口的(python或ruby)。
去一条主要的小溪。考虑到可用的资源,您的技能的未来市场化,丰富的开发者生态系统,我认为您应该从Java或C语言开始。