首页IT科技王垠github(王垠:不再推荐 Haskell_IT新闻_博客园)

王垠github(王垠:不再推荐 Haskell_IT新闻_博客园)

时间2025-06-20 00:07:46分类IT科技浏览3871
导读:投递人 itwriter 发布于 2012-09-14 12:49...

投递人 itwriter 发布于 2012-09-14 12:49 评论(0) 有312人阅读

原文链接

[收藏]

« »

在之前的一篇博文里            ,我推荐从函数式语言入手掌握程序语言          。推荐的两种语言是 Scheme 和 Haskell                 。可是出于多种原因                ,我必须告诉大家     ,我已经不再推荐 Haskell      。这里的原因比较深入         ,可能不容易说清楚                 ,所以只简述一下        。如果有异议的话       ,可以来信跟我讨论      ,这样也可以帮我理清思路                。

先说说之前推荐 Haskell 的原因吧         。推荐它其实是因为是它的类型关系较 Scheme 清晰                  ,并且有模式匹配等方便的功能      。可是类型系统和模式匹配          ,却不是 Haskell 所专有的                。其它的一些语言   ,比如 OCaml 和 Racket 也有很方便的模式匹配和能力相近的类型系统            。

现在停止推荐 Haskell                  ,其实是出于很多原因的积累:

1. 类型系统过于复杂

最开头的时候             ,Haskell 使用的是普通的 Hindley-Milner 类型系统(HM 系统)   。使用这种类型系统的原因是因为程序员不需要写任何类型标记(typeannotation)就可以“静态            ”的确保类型的正确                。可是这样做的代价是,这个类型系统表达能力太弱               。很多程序需要拐弯抹角的绕过这个类型系统的种种限制才写得出来。比如               ,Haskell 的 sum type 导致 constructor 的非常麻烦的多重嵌套                ,这我已经在一篇英文博文里面比较隐晦的批评了一下             。显然 HM 系统灵活性太差   ,所以 Haskell 内部后来引进了 SystemFw                  。可是这些系统发展了好多年            ,还是不能解决问题   。到现在                ,你仍然会在 Haskell 里面遇到莫名其妙的限制          。你觉得程序应该编译通过     ,可是它就是编译不过(比如我这篇英文博客所述)                 。究其原因         ,其实是类型系统有问题                 ,而不是程序员的思路有问题      。

有的 Haskell 程序员可能会反驳       ,说是因为我不能理解 Haskell 的类型系统        。那么我可以告诉你      ,我不但实现了 Haskell 和 ML 所用的 HM 系统                  ,而且实现了比 HM 还要强大的 MLF, intersection type 等类型系统                。Haskell 推导不出来的类型          ,我的系统可以推导出来         。所以我说的话其实是出自第一手的依据      。

2. 参数和返回值的类型标记很有必要

与 Haskell 同门的 SML 和 OCaml 的类型系统也有类似的问题   ,甚至更加严重(比如 ML 有value restriction                  ,导致不必要的约束和困惑)                。但是很多“常规语言                ”             ,特别是像 Java,C++ 等需要类型标记的语言,却没有这个问题            。很多人喜欢 Haskell 都是因为用它可以“不写类型标记     ”               ,可是现在呢                ,最好的 Haskell 程序员都是先把类型写下来   ,才开始写函数   。一来这样思路清晰            ,你知道这函数要处理哪些类型的数据                ,你就明确的把它写下来     ,以后再来看         ,或者给其他人看                 ,都一目了然                。二来是因为 Haskell 的类型系统由于加入的一些“不可判定         ”(undecidable)的扩展功能       ,有时候已经无法推导出类型了               。而给函数的参数和返回值加上类型标记之后      ,就可以轻松推导出类型。所以你看到                  ,给参数和返回值加上类型标记          ,不管是对人还是对机器   ,都有好处             。所以经过我一学期的研究得出的结论是                  ,HM 系统的类型推导             ,其实是多此一举                  。

不过需要注意的是,函数的局部变量               ,其实是不需要类型标记的   。比如在 Java 程序里常见的:

List<String> ls = newArrayList<String>();

这样的赋值语句                ,其实是没必要在左边加一个类型标记的   ,因为右边的类型我们知道          。在这一点上C++11 的 "auto" 是一个正确的方向                 。比如在 C++11 里            ,你可以写:

auto ls =newArrayList<String>();

这种类型推导不难做                ,基本就是一个抽象解释器      。我给 Python 做的PySonar类型推导系统里面就实现了这样的功能        。

对任何语言     ,具体是哪些地方有必要加上类型标记呢?其实有一个很简单的方法来判断:观察信息进出函数的“接口                 ”         ,把这些接口都做上标记                。直观一点说                 ,函数就像是一个电路模块       ,只要我们知道输入和输出是什么      ,那么中间的导线里面是什么                  ,我们其实都可以推出来         。类型推导的过程          ,就像是模拟这个电路的运行      。这里函数的输入就是参数   ,输出就是返回值                  ,所以基本上把这两者加上类型标记             ,里面的局部变量的类型都可以推出来                。另外需要注意的是,如果函数使用了全局变量               ,那么全局变量就是函数的一个“隐性       ”的输入                ,所以如果程序有全局变量   ,都需要加上类型标记            。

3. “纯函数式      ”并不是好主意

我最近常常跟同学开玩笑            ,说“纯函数式                  ”语言是什么意思   。“纯函数式          ”语言是用来描述这样一个世界的                ,在这个世界里     ,所有的东西都是“有线   ”的(wired)                。不存在 3G         ,4G                 ,不存在 wifi       ,收音机      ,卫星电视…… 所谓的 monads                  ,其实就是这个布满电缆的世界里的“接线盒                  ”               。

Haskell 编程之麻烦          ,就是因为这些电缆。你必须小心翼翼的把它们接在一起   ,安排好                  ,否则就会有各种问题             ,甚至绊到脚             。连生成随机数这么简单的事情,你都得学会使用各种各样的“随机数 monads             ”                  。这是因为我们需要记录随机数发生器的“状态”               ,所以随机数 monad 输入一个随机数发生器                ,返回一个随机数以及一个新的随机数发生器!想一想   ,在 C 语言里面            ,你只需要一个全局变量或者函数内部的 static 变量来记录随机数发生器的状态   。到底是谁简单                ,谁复杂?我想你可能已经意识到     ,全局变量其实就是 wifi!

Haskell 的支持者常说         ,纯函数的语言容易“推理               ”                 ,容易确保程序的正确          。因为它的程序就像“数学的函数                ”       ,给同一个输入      ,就会得到同一个输出                 。这叫做“referentialtransparency   ”      。可是这种性质                  ,真的可以让程序容易“推理            ”吗?如果 Haskell 的函数使用了 monads          ,比如“状态                ”(statemonad)   ,那么这个函数的“输入     ”                  ,就几乎永远不会相同        。因为那个状态每次都可能变化             ,所以你实际上还是没法知道那里面是什么!

记住这一点:世界上没有包治百病的神药                。

4. 惰性求值(lazyevaluation)不是好主意

关于惰性求值,我基本同意Robert Harper 的观点         。惰性求值让类型变得混乱               ,让程序的时间和空间复杂度难以分析                ,而且跟并行计算的原则有根本性的矛盾      。而惰性求值的功能   ,却不是经常有用的                。即使需要            ,在普通的语言里也可以通过 thunk 来实现            。所以                ,惰性求值带来的问题恐怕比它解决的问题还要多   。

很多自称“从 Haskell 衍生         ”的语言     ,很多其实都只是有其形         ,而无其实                。一个例子就是Bluespec                 ,一种硬件描述语言               。它虽然自称是从 Haskell 演变来的       ,看起来像 Haskell      ,但是它却不是惰性的                  ,类型系统也很简单          ,所以基本上它已经不是 Haskell。打着 Haskell 的旗号   ,恐怕是想借助 Haskell 的名声来抬高自己                  ,或者是因为 Bluespec 的创造者 Lennart Augustsson 最早的时候是 Haskell 的主要发起人之一             。

5. 思想局限

所以综上所述             ,Haskell 自称的“特性                 ”几乎被实践一一推翻                  。可是 Haskell 程序员往往炫耀自己的“函数式编程       ”水平,其实经常陷入一些很难理解的“设计模式      ”               ,无法自拔   。鉴于这个原因                ,我停止向大家推荐 Haskell          。

另外需要申明一下的是   ,我停止推荐 Haskell 并不是因为我想力推 Scheme                 。实际上 Scheme 也有自己的问题            ,但是相对来说                ,它更加简单易懂     ,符合学习的需要      。另外         ,以前对 C 和 C++ 的批评也许过于偏激        。最近为了在 LLVM 上做一些事情                 ,开始重新理解C++       ,发现它做的好些事情其实是挺不错的      ,甚至超过好些最炫的                  ,带有“dependenttype                  ”的函数式语言                。所以现在我觉得          ,其实世界上的语言并没有什么绝对的标准         。在一段时间认为是错的东西   ,可能却是对的      。所以不用盲目的排斥一些语言                  ,把它们都拿来看一下             ,互相对比,才会知道到底什么是好的                。

声明:本站所有文章               ,如无特殊说明或标注                ,均为本站原创发布            。任何个人或组织   ,在未征得本站同意时            ,禁止复制            、盗用                、采集     、发布本站内容到任何网站         、书籍等各类媒体平台   。如若本站内容侵犯了原著者的合法权益                ,可联系我们进行处理                。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
如何在苹果电脑上安装微信电脑版(苹果macOS Big Sur系统电脑怎么安装微信? mac安装微信的两种方法) 网上有哪些赚钱渠道可以赚钱(有什么网上赚钱的渠道吗-通过增加流量赚钱的几个方法,你知道吗?)