(点击上方公众号,可快速关注)
写本篇文章主要是对Haskell做一些澄清,因为看到网上很多文章都要把它说没了,心里很是不平啊。每种编程语言都有其生命周期,但Haskell肯定在短期内淘汰不了。如果大家时间允许的话,可以抽点时间了解一下这门语言。
本篇文章主要从以下三个方面展开:
写本篇文章的缘由
透析网上某些文章的观点
推荐学习Haskell
缘由
每隔一段时间网上就会出现一些唱衰某些编程语言的文章,文章内容大同小异,标题夺人眼球。我搜集了一下,近一年出现的该类文章主要有:《五种注定将要走向衰败的编程语言》、《定了!2020年,6种将死的编程语言!》、《别瞎学了,这几门语言要被淘汰了!》,这几篇文章我都在不同的时间段内看到过,看来我也是一个八卦心很重的人啊~~ 只要稍加考察一下,这些文章的很多观点都是经不起推敲的。这些文章反复提到了Haskell语言,都对它做出了悲观的、感觉马上就要应验的预测。
这门语言我学习了2年多,也写了一些工具之类的应用,多少算了解一些,从我的感受来讲,挺建议大家学习一下的。现行主要的工业级语言都是命令式的,而它是纯函数式的,即使放在纯函数式这里面,它也有很多不同凡响的设计,比如默认惰性求值。
所以,那些文章里的阐述和预测是有些偏颇的,下面是我的一些观点。
文章观点透析
摘取这几篇文章的观点,一一PK。
“Haskell 是另一个古董级别的编程语言,它于几十年前创建,在90年代一直被使用。”
这里的“古董”是有误导性的,马上可能让人感到“代沟”,产生距离感,近而阻止了跃跃欲试的冲动。
实际上Haskell跟Python的诞生时间差不了多少,都在1990年左右诞生,也有30年了。30年对于一门编程语言来说真的不算长,算不上真的古董,如果真的要选一些古董级的语言,我觉得FORTRAN(1957年)、LISP(1958年)能上榜。人家这两门语言虽然不是主流语言,但也仍然在自己的领域活得好好的。
其次,编程语言从诞生到逐渐应用是需要时间慢慢沉淀的,比如近几年热门的Go语言(2007年)、Rust语言(2009年),很多人会觉得这两门语言是这两年才诞生的,其实不是的,它们也都10多年了。所以,30年对一门语言来说,甚至连少年都没度过,更谈不上古董。
一门语言的是否要淘汰跟“年龄”没有直接的关系,但不可否认的是,随着编程语言理论研究的深入,一些更优的方案会被提出来替代现有的设计,导致语言的一些特性跟时代脱节,但这也无需太多担心,基于两点:(1)编程语言都是不断进化的,不要用静态的眼光看待它们。比如,早期的C++、Java等语言是没有函数式的语法的,但随着函数式编程的兴起,它们都加入了函数式编程的支持;Java不是也是到5.0才加入泛型的支持;(2)语言的淘汰是个长期的过程,对于一门还在上升期的语言来说,短期内淘汰根本就是不可能的。
“对于 Haskell 来说,属于它的时代很快就要结束了。”
Haskell设计的初衷是为了规范函数式编程的研究、应用与发展。上世纪90年代左右,函数式编程语言“群魔乱舞”,而且语法相似且效率不高,所以在FPCA会议上,这些大佬们决定设计一种函数式语言解决这一现状。从近些年的语言发展来看,貌似他们的目的已经达成了,因为现在函数式编程已深入人心。而这恰恰是它最好的时代,Haskell被Facebook、滴滴应用也都是近些年的事,怎么就把人家说过去了呢。
而且,编程语言越来越呈现出领域专用的趋势,只要某种语言在某些领域呈现出自己的特质,它就是很难被淘汰的。举几个例子:在高级语言遍地的今天,C语言仍然在自己的低级编程领域占有重要的席位;Lisp语言语法树的语法,使得程序自己能改写自己,这个能力是其他不同类型的语言不具备的,很多专家系统仍然使用Lisp实现;Lisp有很多方言,每种方言都有不少应用。
在2021年1月TIOBE 编程语言排行榜:Haskell排名44位,还是挺不错的。顺便说一下,这3篇文章唱衰的另一门语言:Visual basic,排名第6。
“研究人员和学者大多将 Haskell 用于构建程序,以对其工作进行复杂的排列和外推计算,但是学起来很难!”
这里有两点需要澄清:
Haskell是通用语言,理论上可以写任何应用,而且某些企业已经在应用了。所以这里的表述会让人以为它就是搞科学计算的,它的应用范围远不止如此。
Haskell真的不难,真的不难,真的不难!!!之所以难,那是因为你在用其他语言的编程经验套在Haskell上。Haskell跟数学的表达很贴近,如果你第一门语言学的是Haskell,大概率是要比学习其它语言顺利的,因为我们每个人从小到大都是学过数学的。
Haskell是纯函数式语言,跟C、C++、Java这些命令式语言的编程思维是不一样的,把这些语言的编程思维硬搬过来是不灵光的。难就难在,从无到有,难在思维的转换上。试想一下,当年你新学C、C++不也是挺懵的。
“难学必然导致非常有限的活跃用户,其实 Haskell 的上一个最新的稳定版本是在 2010 年发布,这已经于事无补了。”
在Haskell用户的调查上,只有50%的用户关注语言特性的扩充上,大部分用户关心的是开发工具等生态的建设上,所以Haskell最近的发力点是在生态上,而不是语言版本的更新上。
这里做个简短的普及:Haskell这门语言主要的编译器是ghc,ghc通过接收开发者提出的不同扩展来达成扩充语言的目的,如果扩展足够成熟,这些扩展就会默认开启,即进入语言标准的行列。这里的2010是指的语言的标准,而ghc是一直在变化的,扩展也是一直的进步的。
所以,用这个论据来证明语言没变化是不成立的。下面我列一份近一年的变化数据:
ghc的变化:2020年发布了8.8.2、8.8.3、8.8.4、8.10.1、8.10.2、8.10.3编译器的正式版,而且9.0和9.1的RC版也已经出来了。
ide工具的支持:haskell-language-server 从5月4日的0.1到了0.8版本,仅仅用了7个月,明显加快了开发速度;而且相应的vscode插件【官方维护】支持基本是傻瓜式的,真是太方便了。2020年以前,能找到好可用的ide工具真的很难,现在好太多了。
除了以上两个主要的变化,其他方面的变化也是可见的,比如包管理器Stack、Cabal等,这里就不展开了。
推荐Haskell
推荐学习Haskell的理由,我主要列出以下四点,前三点主要关于语言本身上的优点,第四点是工程上的优势:
纯函数式
函数式编程中,函数作为第一公民,上世纪50年代lisp语言就支持了,但真正还是这几年才火的,好多语言都引入了函数式的语言结构,你可以在熟悉的语言里找到佐证。而Haskell的“纯”体现在:它将副作用特殊对待,显式地与其他部分区分开来。好多人以为纯函数式语言没有副作用,这是不对的,这里需要特别澄清一下。
这样做可以保证没有副作用的函数具有引用透明性的性质,即对于同样的输入,函数都返回同样的结果。好处是这样的纯函数更好的测试、debug、分析,而有副作用的函数,则需要更多的精力对待,它们是问题出现时,重点关注的对象。其他编程语言上也是提倡这种思想的,只是它们没有显式的语言层面支持,只能由程序员自己控制,不同的程序员的水平是不一样,出现的最终结果有不尽相同。比如,C++中,返回int
的函数保不准也有副作用,而在Haskell中,返回为Int
的函数可以认为就是没有副作用,因为副作用在IO
中是不可逃逸的。
强静态类型
Haskell的类型系统很强大,能在编译时确定每个表达式的类型,即静态类型,这样主要带来两个好处:
错误及早发现,不用等到运行才发现
一些动态类型的语言,比如Python,有些bug可能运行很长时间才会被发现。及早的发现问题,对程序的健壮性异常重要。
利于编译器优化,带来性能提升
经验上,一般静态类型的语言都要比动态类型的语言效率高,主要是静态类型能给编译器更多的程序信息,利于编译器对程序进行优化。
强体现在Haskell对类型检查极为严格,保证不会出现类型约束以外的行为。而C/C++虽然也是静态类型语言,但类型检查的强度并不如Haskell,比如enum类型可以当作整型使、int
类型可以自动提升到double
用,等等。而在Haskell中,是不会有这种隐式的默许行为的。
Haskell的强静态类型带来的另外一个好处是:类型的自动推导(type inferrece),免去类型声明,可以实现类似Python编程的便捷。当然,很多语言也声称有类型推导,但此类型推导非彼类型推导,这里拿C++举例。在C++也有auto
关键字实现“类型推导(type reduction)”,但功能就弱多了。Haskell能根据绑定的使用情况推导出绑定的类型,而C++中的auto
只能根据声明语句中,赋值符号右侧的类型推导出变量的类型,推导的局限性还是挺大的。
语言影响力大
下图来源于https://programminglanguages.info/influence-network/,这个网站专门根据最新的编程语言之间的衍生关系绘制了图谱,截至该文章完成最新的数据更新于2020年12月28日。直观上,节点越大标识该语言对其他语言的影响力越大。从图中可以看到,Haskell对其他的影响力是非常大的,这说明掌握Haskell对学习其他语言是有好处的。有兴趣的读者可以登录该网页,选择感兴趣的语言,看看该语言影响了哪些语言的发展。
方便的包管理
这一点实际上不是Haskell特有的强项,基本上现代有良心的编程语言都提供了方便好用的包管理工具,比如Rust的cargo,Java的maven等。在Haskell中,主要有两个包管理工具:stack、cabal。使用包管理工具,能方便地对项目进行管理,包括创建项目、引入外部依赖、打包等等操作,我甚至以为有没有包管理工具才是衡量一门语言是否现代化的标志。
再次吐槽一下C++,C++到现代还没有一个成熟、应用广泛地包管理工具,每每编译编译三方包恨得牙根疼,简直没有更麻烦。
除此之外,Haskell的惰性求值也是其一大亮点,好处是保证程序运行免去不必要的计算,当然也有一些缺点,这里就不展开了。Haskell时一门很好的语言,不光可以用于工作,也能开拓视野,培养良好的编程思维。据我了解,有些人在解决一些问题时,就是先用Haskell写出原型,然后使用其他语言实现的,因为同样的语法结构,在Haskell中要更清晰直接。
~~完结,感谢阅读。
喜欢我的文章,请关注我的公众号,转载请标明出处。