在Haskell之后要学习什么语言?

dan*_*tin 85 haskell programming-languages

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

然而,Haskell中的编程就像巫术,我想拓宽我对编程的了解.我想选择一种新的编程语言来学习,但我没有足够的时间来学习任意语言,删除它并重复.所以我想我会在这里提出问题,以及关于我正在寻找的语言类型的几个规定.有些是主观的,有些是为了缓解从Haskell的过渡.

  • 强类型系统.我最喜欢的Haskell编程部分之一是编写类型声明.这有助于构建我对各个功能及其与整个程序的关系的想法.它还可以更容易地非正式地推断我的程序的正确性.我关心的是正确性,而不是效率.
  • 强调递归而不是迭代.我在Haskell中使用迭代构造,但是递归地实现它们.但是,理解递归函数的结构要比复杂的迭代过程容易得多,尤其是在使用组合器和高阶函数(如map,folds和bind)时.
  • 有意识地学习.Haskell是一种有用的语言.它有点像读康德.然而,我几年前与C的经历并非如此.我不是在寻找C.语言应该强制执行一个概念上有趣的范例,在我完全主观的看法中,C-like不会.

称重答案:当然,这些只是笔记.我只想回复所有给出良好反应的人.你一直非常乐于助人.

1)一些回答表明强调递归的强大的静态类型语言意味着另一种功能语言.虽然我想继续与Haskell合作,但是camccann和larsmans正确地指出另一种这样的语言会"过度缓解过渡".这些评论非常有用,因为我不打算在Caml中编写Haskell!在证明助理中,Coq和Agda看起来都很有趣.特别是,Coq将为建构逻辑和形式类型理论提供可靠的介绍.我花了一点时间使用一阶谓词和模态逻辑(Mendellsohn,Enderton,一些Hinman),所以我可能会对Coq有很多乐趣.

2)其他人非常青睐Lisp(Common Lisp,Scheme和Clojure).从我收集的内容来看,Common Lisp和Scheme都有很好的介绍性材料(On LispThe Reasoned Schemer,SICP).SICP中的材料使我倾向于Scheme.特别是,通过SICP的Scheme将涵盖不同的评估策略,懒惰的实现,以及关注诸如延续,解释器,符号计算等主题的机会.最后,正如其他人所指出的那样,Lisp对代码/数据的处理将是全新的.因此,我倾向于选择(2),一个Lisp.

3)第三,Prolog.Prolog有很多有趣的材料,它的主要领域正是我感兴趣的.它具有简单的语法并且易于阅读.我现在无法评论更多,但在阅读了Prolog的概述并浏览了一些介绍材料之后,它排名为(2).似乎Prolog的回溯总是被黑客入侵Haskell!

4)在主流语言中,Python看起来最有趣.蒂姆耶茨使这些语言听起来非常吸引人.显然,Python经常被教给第一年的CS专业; 所以它要么在概念上丰富,要么易于学习.我需要做更多的研究.

谢谢大家的推荐!它看起来像Lisp(Scheme,Clojure),Prolog或像Coq或Agda这样的证明助手是推荐的主要语言.

C. *_*ann 85

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

强类型系统.(...)它还使我的程序的正确性非正式地推理.我关心的是正确性,而不是效率.

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

你可能会在这里放松过度,我担心.非常严格的类型系统和纯粹的功能风格是Haskell的特征,几乎任何类似于主流编程语言的东西都需要至少在某些方面妥协.因此,考虑到这一点,这里有一些广泛的建议,旨在保留你似乎喜欢Haskell的大部分内容,但有一些重大转变.

  • 无视实用性并选择"比Haskell更多的Haskell":由于不确定性和其他混乱的妥协,Haskell的类型系统充满了漏洞.清理混乱并添加更强大的功能,您可以获得CoqAgda等语言,其中函数的类型包含其正确性的证明(您甚至可以将函数箭头->视为逻辑含义!).这些语言已用于数学证明和具有极高正确性要求的程序.Coq可能是该风格中最突出的语言,但Agda具有更多Haskell-y的感觉(以及用Haskell本身编写).

  • 无视类型,添加更多魔法:如果Haskell是巫术,Lisp是创造的原始,原始魔力.Lisp系列语言(包括SchemeClojure)具有几乎无与伦比的灵活性和极端极简主义.这些语言基本上没有语法,直接以树数据结构的形式编写代码; 在某些语言中,Lisp中的元编程比非元编程更容易.

  • 妥协一点并接近主流:Haskell属于受ML影响的广泛语言家族,你可以在没有太多困难的情况下转移到其中.Haskell是功能风格类型和使用的正确性保证中最严格的一种,其他的通常是混合风格和/或出于各种原因做出务实的妥协.如果您想要接触OOP并访问许多主流技术平台,可以使用JVM上的ScalaF#.NET与Haskell有许多共同之处,同时提供与Java和.NET平台的轻松互操作性.微软直接支持F#,但与非Windows平台上的Haskell和可移植性问题相比,它有一些烦人的限制.Scala直接与更多Haskell类型系统和Java的跨平台潜力相对应,但具有更重量级的语法,缺乏F#所享有的强大的第一方支持.

大多数建议也在其他答案中提到,但希望我的理由可以提供一些启示.

  • @Lucas:Haskell的重要优势与缺乏高级别的多态性和类型类.除此之外,相当多的[GHC特定扩展](http://www.haskell.org/ghc/docs/latest/html/users_guide/ghc-language-features.html)非常好.无论如何都不是致命的缺陷,但在习惯了Haskell后,感觉有点笨拙没有那些东西.想象一下从现代C#回到使用C#1.x ...... (7认同)
  • 我是__Coq__和__Agda__的家人,你也可以看看[Qi II](http://www.lambdassociates.org/). (4认同)

Chu*_*uck 20

我将成为那个家伙,并建议你要求做错事.

首先,你说你想开阔你的视野.然后你描述了你想要的那种语言,它的视野听起来就像你已经拥有的视野一样.通过一遍又一遍地学习同样的东西,你不会获得太多收获.

我建议你学习一个Lisp - 即Common Lisp,Scheme/Racket或Clojure.它们都是默认动态类型,但具有某种类型提示或可选的静态类型.球拍和Clojure可能是你最好的赌注.

Clojure是最近的,并且有更多的Haskellism,比如默认的不变性和大量的懒惰评估,但它基于Java虚拟机,这意味着它有一些奇怪的瑕疵(例如JVM不支持尾部调用消除,所以递归是友好的一个黑客).

Racket比较老,但在此过程中已经获得了很多功能,例如静态类型支持和对功能编程的关注.我想你可能会从Racket中获得最大收益.

Lisps中的宏系统非常有趣,并且比你在其他地方看到的任何东西都强大得多.仅这一点至少值得关注.

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

scl*_*clv 19

从适合您的专业的角度来看,显而易见的选择似乎是一种逻辑语言,如Prolog或其衍生产品.逻辑编程可以用函数语言非常巧妙地完成(参见,例如The Reasoned Schemer),但您可能喜欢直接使用逻辑范例.

一个交互式定理证明系统,如twelf或coq也可能会引起你的兴趣.

  • 当您对强类型语言表示兴趣时,我建议使用lambdaProlog,一种类型化的高阶逻辑编程语言.一个编译的实现是Teyjus - http://code.google.com/p/teyjus(披露:我在Teyjus工作). (2认同)

Tho*_*son 18

我建议你学习Coq,这是一个强大的证明助手,语法让Haskell程序员感到舒服.关于Coq的酷炫之处在于它可以被提取到其他功能语言,包括Haskell.Hackage上甚至还有一个用Coq编写的软件包(Meldable-Heap),有关其操作的属性,然后提取到Haskell.

另一种提供比Haskell更强大功能的流行语言是Agda - 我不知道Agda除了知道它是依赖于Hackage之外的类型,并且受到我尊重的人的尊重,但这些对我来说是足够好的理由.

我不希望其中任何一个变得容易.但是如果你知道 Haskell并想要使用比Haskell类型系统更强大的语言,那么就应该考虑它们.

  • 同样值得注意的是,如果作为一名哲学专业,他在形式逻辑方面有很多经验,那么Curry-Howard风格的证明助手对他来说可能会比对大多数资深程序员更不感到困惑! (5认同)

dan*_*lei 11

由于除了你的主观兴趣之外你没有提到任何限制并且强调"奖励学习"(好吧,好吧,我会忽略静态类型限制),我建议学习几种不同范式的语言,最好是那些他们每个人都是"典型的".

  • 一种Lisp方言,用于代码作为数据/同音性的东西,因为它们是动态(或多或少严格)函数式编程语言的好例子,如果不是最好的例子
  • Prolog是主要的逻辑编程语言
  • Smalltalk作为一种真正的OOP语言(也很有趣,因为它通常采用极其以图像为中心的方法)
  • 如果您对并发/并行/分布式编程伪造的语言感兴趣,可能是ErlangClojure
  • 第四堆栈的面向对象编程
  • (Haskell用于严格的功能静态类型惰性编程)

特别是Lisps(CL不如Scheme)和Prolog(和Haskell)包含递归.

虽然我不是这些语言中的任何一个大师,但我确实花了一些时间在他们每个人身上,除了Erlang和Forth,他们都给了我大开眼界和有趣的学习经历,因为每个人都从不同的角度解决问题.

所以,虽然看起来我似乎忽略了你没有时间尝试几种语言的部分,但我认为花在任何这些上面的时间都不会浪费,你应该看看所有这些.


Cor*_*rch 10

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

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

Dobbs博士在2008年发表了一篇关于Cat 的短文,尽管该语言略有改变.


yat*_*975 10

如果你想要一个强大的(呃)类型的Prolog,水星是一个有趣的选择.我过去曾涉足过它,我喜欢它给我的不同观点.它还具有类型系统中的moded-ness(哪些参数需要是空闲/固定的)和确定性(有多少结果?).

Clean与Haskell非常相似,但具有唯一性类型,可用作Monads(更具体地说,IO monad)的替代品.唯一性输入也有助于处理数组.


MaD*_*D70 9

我有点迟了但是我发现没有人提到过几种范式和相关语言,它们可以让你感兴趣的是它们的高级抽象和通用性:


Tim*_*tes 8

尽管它未能满足您的一个重要标准(静态*打字),我将为Python提供一个案例.以下是我认为你应该看一下的几个原因:

  • 对于命令式语言,它具有令人惊讶的功能.这是我学习它时让我印象深刻的事情之一.以列表推导为例.它具有lambdas,一流的功能,以及许多功能启发的迭代器组合(地图,折叠,拉链......).它让您可以选择最适合问题的范例.
  • 恕我直言,就像Haskell一样,编码很漂亮.语法简单而优雅.
  • 它有一种文化,专注于以直截了当的方式做事,而不是过于专注于效率.

我明白你是否正在寻找别的东西.例如,正如其他人所建议的那样,逻辑编程可能正好在你的小巷里.


*我认为你的意思是静态输入,因为你想声明类型.从技术上讲,Python 一种强类型语言,因为你不能随意将字符串解释为数字.有趣的是,有些Python衍生产品允许静态输入,比如Boo.

  • 真?我认为Python对于那些没有做过多功能编程的人来说似乎特别有用.我已经使用了相当多的Python和Haskell,虽然Python是一种很好的语言,当然从函数式语言中借用了一些东西,但它仍然是99%的必要条件. (16认同)

Muh*_*uri 8

根据您的描述,我会建议OcamlF#.

ML系列在强类型系统方面通常非常好.强调递归和模式匹配也很清楚.

在哪里,我有点犹豫是否有奖励学习部分.毫无疑问,学习它们对我来说是有益的.但是考虑到你的限制和对你想要的描述,你似乎并没有真正寻找与Haskell有更多不同的东西.

如果你没有提出你的限制,我会建议使用PythonErlang,这两种方法都会让你走出自己的舒适区.


Hyn*_*dil 8

我会推荐你​​Erlang.它不是强类型语言,你应该尝试一下.这是一种非常不同的编程方法,您可能会发现存在强类型不是最佳工具(TM)的问题.无论如何,Erlang为您提供静态类型验证(typer,dialyzer)的工具,您可以在从中获益的部分使用强类型.它可以为你带来有趣的体验,但要做好准备,感觉会有很大不同.如果您正在寻找"概念上有趣的范例",您可以在Erlang中找到它们,消息传递,内存分离而不是共享,分发,OTP,错误处理和错误传播,而不是错误"预防"等等.如果你有C和Haskell的经验,Erlang可能会远离你目前的经验,但仍然在脑子里发痒.


Fre*_*Foo 6

根据我的经验,强类型+强调递归意味着另一种函数式编程语言.然后,我想知道这是否非常有益,因为它们都不像Haskell那样"纯粹".

正如其他海报所建议的那样,Prolog和Lisp/Scheme都很不错,尽管两者都是动态类型的.许多有着强烈理论"品味"的好书已经出版了关于Scheme的特别.看看SICP,它也传达了许多通用的计算机科学智慧(元循环解释器等).

  • 第一段+1,正是我在阅读问题时的想法.为了学习新东西,我建议使用一种现代命令式语言,比如Python - **尤其是**,因为它不是OP所习惯的(动态类型,遍布各地的迭代器等).它还有非常酷的高级概念,如元类或生成器(与惰性列表惊人相似)/生成器表达式(用作列表推导+生成器的泛化).另外,dict和set comprehensions规则. (4认同)
  • @delnan:Haskell也有列表推导,并且可以使用Haskell的标准列表类型在Haskell中轻松表示生成器/迭代器.因此,在我看来,两种语言之间最大的区别在于面向对象编程和(通常)不纯的数据结构,如字典. (3认同)

leo*_*lao 6

因素将是一个不错的选择.


小智 5

你可以开始研究Lisp.

Prolog也是一种很酷的语言.


kal*_*dic 5

如果您决定偏离您对类型系统的偏好,您可能会对J编程语言感兴趣.它如何强调功能构成非常出色.如果你喜欢Haskell中的无点风格,J的隐性形式将是有益的.我发现它非常引人深思,特别是在语义方面.

没错,它不符合你对你喜欢什么的偏见,但请看一看.只知道它在那里是值得发现的.完整实现的唯一来源是J Software,jsoftware.com.