发明精通一门编程语言言,并推广是不是会很有钱

抓住编程语言的本质
服务器君一共花费了150.109 ms进行了4次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议
这篇文章曾经叫做《初学者程序语言的选择》,但是后来我发现,这里给出的看法其实不只是给初学者看的,甚至可能会让初学者看不懂。而就我在 Google 实习的时候的观察看来,很多写了几十年程序的资深程序员,可能也没有明白这里指出的道理。所以我把题目改了一下,并且加入了新的内容,希望对新手和老手都有所帮助。
作者 / 王垠 (还记得那个从清华退学的博士王垠吗?XD)
学习程序语言是每个程序员的必经之路。可是这个世界上有太多的,每一种都号称具有最新的“特性”。所以程序员的苦恼就在于总是需要学习各种稀奇古怪的语言,而且必须紧跟“潮流”,否则就怕被时代所淘汰。
作为一个程序语言的研究者,我深深的知道这种心理产生的根源。程序语言里面其实有着非常简单,永恒不变的。看到了它们,就可以一劳永逸的掌握所有的程序语言,而不是只见树木不见森林。我想写一本书,试图用最简单的方式来解释程序语言(以至于计算机科学)的根本性原理,从而让人可以在非常短的时间内掌握所有程序语言的精髓。但是在还没有完成之前,我想先提出一些建议和参考书。
对程序语言的各种误解
学习程序语言的人,经常会出现以下几种心理,以至于他们会觉得有学不完的东西,或者走上错误的道路。以下我把这些心理简要分析一下,希望可以消除一些疑惑。
追求“新语言”。
基本的哲学告诉我们,新出现的事物并不一定是“新事物”,它们有可能是历史的倒退。事实证明,新出现的语言,很多还不如早就存在的。正视这个事实吧,现代语言的多少“新概念”不存在于最古老的一些语言里呢?程序语言就像商品,每一家其实都是在打广告。而绝大多数的设计,包括某些最“艰深”最“理论”的语言里面的概念,都可能是肤浅而短命的。如果你看不透这些东西的设计,就会被它们蒙蔽住。过度的热情和过多的宣传,往往意味着肤浅。很多语言设计者其实并不真的懂得程序语言设计的原理,所以常常在设计中重复的犯前人犯过的错误。但是为了推销自己的语言和系统,他们必须夸夸其谈,进行宗教式的宣传。
“存在即是合理”。
记得某名人说过:“不能带来新的思维方式的语言,是没有必要存在的。”他说的是相当正确的。世界上有这么多的语言,有哪些带来了新的思维方式呢?其实少之又少。绝大部分的语言给世界带来的不过是混乱。有人可能反驳说:“你怎么能说 A 语言没必要存在?我要用的那个库 L,别的语言不支持,只能用 A。”但是注意,他说的是存在的“必要性”。如果你把存在的“事实”作为存在的“必要性”,那就逻辑错乱了。就像如果二战时我们没能打败希特勒,现在都做了他的奴隶,然后你就说:“希特勒应该存在,因为他养活了我们。”显然这个逻辑有问题,因为如果历史走了另外一条路(即希特勒不存在),我们会过上自由幸福的生活,所以希特勒不应该存在。对比一个东西存在与不存在的两种可能的后果,然后做出判断,这才是正确的逻辑。按照这样的推理,如果设计糟糕的 A 语言不存在,那么设计更好的 B 语言很有可能就会得到更多的支持,从而实现甚至超越 L 库的功能。
追求“新特性”。
程序语言的设计者总是喜欢“发明”新的名词,喜欢炒作。普通程序员往往看不到,大部分这些“新概念”其实徒有高深而时髦的外表,却没有实质的内涵。常常是刚学会一个语言 A,又来了另一个语言 B,说它有一个叫 XYZ 的新特性。于是你又开始学习 B,如此继续。在内行人看来,这些所谓的“新特性”,绝大部分都是新瓶装老酒。很多人写论文喜欢起这样的标题:《XYZ:A Novel Method for ...》。这造成了概念的爆炸,却没有实质的进步。可以说这是计算机科学最致命的缺点。
追求“小窍门”。
很多编程书喜欢卖弄一些小窍门,让程序显得“短小”。比如它们会跟你讲 "(i++) - (++i)" 应该得到什么结果;或者追究运算符的优先级,说这样可以少打括号;要不就是告诉你“if 后面如果只有一行代码就可以不加花括号”,等等。殊不知这些小窍门,其实大部分都是程序语言设计的败笔或者历史遗留问题。它们带来的不是清晰的思路,而是是逻辑的混乱和认知的负担。比如 C 语言的 ++ 运算符,它的出现是因为 C 语言设计者们当初用的计算机内存小的可怜,而 "i++" 显然比 "i=i+1" 少 2 个字符,所以他们觉得可以节省一些空间。现在我们再也不缺那点内存,可是 ++ 运算符带来的混乱和迷惑,却流传了下来。现在最新的一些语言,也喜欢耍这种语法上的小把戏。如果你追求这些小窍门,往往就抓不住精髓。
针对“专门领域”。
很多语言没有新的东西,为了占据一方土地,就号称自己适合某种特定的任务,比如文本处理,数据库查询,WEB编程,游戏设计,并行计算,或者别的什么专门的领域。但是我们真的需要不同的语言来干这些事情吗?其实绝大部分这些事情都能用同一种通用语言来解决,或者在已有语言的基础上做很小的改动。只不过由于各种政治和商业原因,不同的语言被设计用来占领市场。就学习而言,它们其实是无关紧要的,而它们带来的“多语言协作”问题,其实差不多掩盖了它们带来的好处。其实从一些设计良好的通用语言,你可以学会所有这些“专用语言”的精髓。后面我会推荐一两个这样的语言。
我必须指出,以上这些心理不但对自己是有害的,而且对整个业界有很大的危害。受到这些思想教导的人进入了公司,就会开始把他们曾经惧怕的这些东西变成教条,用来筛选新人,从而导致恶性循环。
如何掌握所有的程序语言
可以老实的说,对几乎所有风格的程序语言,我都有专家级的见解。它们在我的头脑里如此简单,以至于我不再是任何语言(包括函数式语言)的“支持者”。但是我花费了太多的时间去摸索这条道路,我希望能够提取出一些“窍门”,可以帮助人们在短时间内达到这种通用的理解。具体的细节足够写成一本书,我现在只在这里提出一些初步的建议。
1. 专注于“精华”和“原理”。
就像所有的科学一样,程序语言最精华的原理其实只有很少数几个,它们却可以被用来构造出许许多多纷繁复杂的概念。但是人们往往忽视了简单原理的重要性,匆匆看过之后就去追求最新的,复杂的概念。他们却没有注意到,绝大部分最新的概念其实都可以用最简单的那些概念组合而成。而对基本概念的一知半解,导致了他们看不清那些复杂概念的实质。比如这些概念里面很重要的一个就是递归。国内很多学生对递归的理解只停留于汉诺塔这样的程序,而对递归的效率也有很大的误解,认为递归没有循环来得高效。而其实递归比循环表达能力强很多,而且效率几乎一样。有些程序比如解释器,不用递归的话基本没法完成。
2. 实现一个程序语言。
学习使用一个工具的最好的方式就是制造它,所以学习程序语言的最好方式就是实现一个程序语言。这并不需要一个完整的编译器,而只需要写一些简单的解释器,实现最基本的功能。之后你就会发现,所有语言的新特性你都大概知道可以如何实现,而不只停留在使用者的水平。实现程序语言最迅速的方式就是使用一种像 Scheme 这样代码可以被作为数据的语言。它能让你很快的写出新的语言的解释器。我的 GitHub 里面有一些我写的解释器的例子(比如这个短小的实现了 Haskell 的 lazy 语义),有兴趣的话可以参考一下。
几种常见风格的语言
下面我简要的说一下几种常见风格的语言以及它们的问题。注意这里的分类不是严格的学术性质的分类,有些在概念上可能有所重叠。
1. 面向对象语言
事实说明,“面向对象”这整个概念基本是错误的。它的风靡是因为当初的“软件危机”(天知道是不是真的存在这危机)。设计的初衷是让“界面”和“实现”分离,从而使得下层实现的改动不影响上层的功能。可是大部分面向对象语言的设计都遵循一个根本错误的原则:“所有的东西都是对象(Everything is an object)。”以至于所有的函数都必须放在所谓的“对象”里面,从而不能直接被作为参数或者变量传递。这导致很多时候需要使用繁琐的设计模式(design patterns) 来达到甚至对于 C 语言都直接了当的事情。而其实“界面”和“实现”的分离,并不需要把所有函数都放进对象里。另外的一些概念,比如继承,重载,其实带来的问题比它们解决的还要多。
“面向对象方法”的过度使用,已经开始引起对整个业界的负面作用。很多公司里的程序员喜欢生搬硬套一些不必要的设计模式,其实什么好事情也没干,只是使得程序冗长难懂。不得不指出,《Design Patterns》这本书,是这很大一部分复杂性的罪魁祸首。不幸的是,如此肤浅,毫无内容,偷换概念的书籍,居然被很多人捧为经典。
那么如何看待具备高阶函数的面向对象语言,比如 Python,JavaScript,Ruby,Scala?当然有了高阶函数,你可以直截了当的表示很多东西,而不需要使用设计模式。但是由于设计模式思想的流毒,一些程序员居然在这些不需要设计模式的语言里也采用繁琐的设计模式,让人哭笑不得。所以在学习的时候,最好不要用这些语言,以免受到不必要的干扰。到时候必要的时候再回来使用它们,就可以取其精华,去其糟粕。
2. 低级过程式语言
那么是否 C 这样的“低级语言”就会好一些呢?其实也不是。很多人推崇 C,因为它可以让人接近“底层”,也就是接近机器的表示,这样就意味着它速度快。这里其实有三个问题:
接近“底层”是否对于初学者是好事?
“速度快的语言”是什么意思?
接近底层的语言是否一定速度快?
对于第一个问题,答案是否定的。其实编程最重要的思想是高层的语义(semantics)。语义构成了人关心的问题以及解决它们的算法。而具体的实现(implementation),比如一个整数用几个字节表示,虽然还是重要,但却不是至关重要的。如果把实现作为学习的主要目标,就本末倒置了。因为实现是可以改变的,而它们所表达的本质却不会变。所以很多人发现自己学会的东西,过不了多久就“过时”了。那就是因为他们学习的不是本质,而只是具体的实现。
其次,谈语言的“速度”,其实是一句空话。语言只负责描述一个程序,而程序运行的速度,其实绝大部分不取决于语言。它主要取决于 1)算法 和 2)编译器的质量。编译器和语言基本是两码事。同一个语言可以有很多不同的编译器实现,每个编译器生成的代码质量都可能不同,所以你没法说“A 语言比 B 语言快”。你只能说“A 语言的 X 编译器生成的代码,比 B 语言的 Y 编译器生成的代码高效”。这几乎等于什么也没说,因为 B 语言可能会有别的编译器,使得它生成更快的代码。
我举个例子吧。在历史上,Lisp 语言享有“龟速”的美名。有人说“Lisp 程序员知道每个东西的值,却不知道任何事情的代价”,讲的就是这个事情。但这已经是很久远的事情了,现代的 Lisp 系统能编译出非常高效的代码。比如商业的 Chez Scheme 编译器,能在5秒钟之内编译它自己,编译生成的目标代码非常高效。它的实现真的令人惊叹,因为它的作者 R. Kent Dybvig 几乎不依赖于任何已有的软件和设计。这个编译器从最初的 parser,到宏扩展,语义分析,寄存器分配,各种优化,…… 一直到汇编器,函数库,全都是他一个人写的。它可以直接把 Scheme 程序编译到多种处理器的机器指令,而不通过任何第三方软件。它内部的一些算法,其实比开源的 LLVM 之类的先进很多。但是由于是商业软件,这些算法一直被作为机密没有发表。
另外一些函数式语言也能生成高效的代码,比如 OCaml。在一次程序语言暑期班上,Cornell 的 Robert Constable 教授讲了一个故事,说是他们用 OCaml 重新实现了一个系统,结果发现 OCaml 的实现比原来的 C 语言实现快了 50 倍。经过 C 语言的那个小组对算法多次的优化,OCaml 的版本还是快好几倍。这里的原因其实在于两方面。第一是因为函数式语言把程序员从底层细节中解脱出来,让他们能够迅速的实现和修改自己的想法,所以他们能够迅速的找到更好的算法。第二是因为 OCaml 有高效的编译器实现,使得它能生成很好的代码。
从上面的例子,你也许已经可以看出,其实接近底层的语言不一定速度就快。因为编译器这种东西其实可以有很高级的“智能”,甚至可以超越任何人能做到的底层优化。但是编译器还没有发展到可以代替人来制造算法的地步。所以现在人需要做的,其实只是设计和优化自己的高层算法。
3. 高级过程式语言
很早的时候,国内计算机系学生的第一门编程课都是 Pascal。Pascal 是很好的语言,可是很多人当时都没有意识到。大一的时候,我的 Pascal 老师对我们说:“我们学校的教学太落后了。别的学校都开始教 C 或者 C++ 了,我们还在教 Pascal。”现在真正理解了程序语言的设计原理以后我才真正的感觉到,原来 Pascal 是比 C 和 C++ 设计更好的语言。它不但把人从底层细节里解脱出来,没有面向对象的思维枷锁,而且含有函数式语言的一些特征(比如可以嵌套函数定义)。可是由于类似的误解和误导,Pascal 这样的语言已经几乎没有人用了。这并不很可惜,因为它的精髓,其实已经存在于像 Scheme 这样的函数式语言里。Scheme 也有赋值语句,所以它实质上含有 Pascal 的所有功能。所以现在的含有赋值语句的函数式语言,可以被看作是是高级过程式语言的“改良版本”。
4. 函数式语言
函数式语言相对来说是当今最好的设计,因为它们不但让人专注于算法和对问题的解决,而且没有面向对象语言那些思维的限制。但是需要注意的是并不是每个函数式语言的特性都是好东西。它们的支持者们经常把缺点也说成是优点,结果它们其实还是被挂上一些不必要的枷锁。比如 OCaml 和 SML,因为它们的类型系统里面有很多不成熟的设计,导致你需要记住太多不必要的限制。
很多人推崇“纯函数式”语言(比如 Haskell,Clean),而极力反对其它的带有“赋值”语句的语言(比如 Scheme 和 ML)。这其中的依据其实是站不住脚的。如果你写过一个函数式语言的编译器,你就会了解如何把一个纯函数式语言翻译成机器指令。这些高级的编译器变换(比如 CPS 和 ANF),其实在本质上揭示了纯函数式语言的本质。它们其实与带有赋值语句的语言没有本质上的区别,但是由于没有赋值语句,一些事情必须拐弯抹角的实现。理智的使用局部变量或者数组的赋值,会使程序更加简单,容易理解,甚至更加高效。
5. 逻辑式语言
逻辑式语言(比如 Prolog)是一种超越函数式语言的新的思想,所以需要一些特殊的训练。逻辑式语言写的程序,是能“反向运行”的。普通程序语言写的程序,如果你给它一个输入,它会给你一个输出。但是逻辑式语言很特别,如果你给它一个输出,它可以反过来运行,给你所有可能的输入。其实通过很简单的方法,可以顺利的把程序从函数式转换成逻辑式的。但是逻辑式语言一般要在“pure”的情况下(也就是没有复杂的赋值操作)才能反向运行。所以学习逻辑式语言最好是从函数式语言开始,在理解了递归,模式匹配等基本的函数式编程技巧之后再来看 Prolog,就会发现逻辑式编程简单了很多。
可是学习编程总要从某种语言开始。那么哪种语言呢?其实每种语言都有自己的问题,以至于在我未来的书里,会使用一种非常简单的语言,它含有所有语言的精髓,却不带有多余的东西。可是在我完成这本书之前,我想先推荐一两个现成的语言。
就我的观点,首先可以从 Scheme 入门,然后学习一些 Haskell (但不是全部),之后其它的也就触类旁通了。你并不需要学习它们的所有细枝末节,而只需要学习最精华的部分。所有剩余的细节,会在实际使用中很容易的被填补上。我后面会提一下哪些是精华的,哪些是最开头没必要学的。
从 Scheme(而不是 Haskell)作为入门的第一步,是因为:
Scheme 没有像 Haskell 那样的静态类型系统 (static type system)。并不是说静态类型不好,但是我不得不说,Haskell 那样的静态类型系统,还远远没有发展到可以让人可以完全的写出符合事物本质的程序来。比如,一些重要的概念比如 Y combinator,没法用 Haskell 直接写出来。当然你可以在 Haskell 里面使用作用类似 Y combinator 的东西(比如 fix,或者利用它的 laziness),但是这些并不揭示递归的本质,你只是在依靠 Haskell 已经实现的递归来进行递归,而不能实际的体会到递归是如何产生的。而用 Scheme,你可以轻松的写出 Y combinator,并且实际的投入使用。
Scheme 不需要 monad。Haskell是一个“纯函数式” (purely functional) 的语言,所有的“副作用”(side-effect),比如打印字符到屏幕,都得用一种故作高深的概念叫 monad 实现。这种概念其实并不是本质的,它所有的功能都可以通过“状态传递” (state passing) 来实现。通过写状态传递程序,你可以清楚的看到 monad 的本质。可以说 monad 是 Haskell 的一个“设计模式”。过早的知道这个东西,并不有助于理解函数式程序设计的本质。
那么为什么又要学 Haskell?那是因为 Haskell 含有 Scheme 缺少的一些东西,并且没有 Scheme 设计上的一些问题。比如:
模式匹配:Scheme 没有一个标准的,自然的模式匹配(pattern matching) 系统,而 Haskell 的模式匹配是一个优美的实现。也有些 Scheme 的扩展实现(比如 Racket)具有相当好的模式匹配机制。
类型:Scheme 把所有不是 #f (false)的值都作为 true,这是不对的。Haskell 里面的 Boolean 就只有两个值:True 和 False。Scheme 程序员声称这样可以写出简洁的代码,因为 (or x y z) 可以返回一个具体的值,而不只是一个布尔变量。但是就为了在少数情况下可以写出短一点的代码,是否值得付出如此沉痛的代价?我看到这个设计带来了很多无需有的问题。
宏系统:宏 (macro) 通常被认为是 Lisp 系列语言的一个重要优点。但是我要指出的是,它们并不是必要的,至少对于初学者是这样。其实如果一个语言的语义设计好了,你会几乎不需要宏。因为宏的本质是让程序员可以自己修改语言的设计,添加新的构造。可是宏的主要缺点是,它把改变语言这种极其危险的“权力”给人滥用了。其实只有极少数的人具有改变一个语言所需的智慧和经验。如果让普通程序员都能使用宏,那么程序将变得非常难以理解。所以其实一般程序员都不需要学习宏的使用,也不必为略过这个东西而产生负罪感。等你进步到可以设计自己的程序语言,你自然会明白宏是什么东西。
(注意,这些是我自己的观点,并不代表 Scheme 设计者们的观点。)
推荐的书籍
《The Little Schemer》:我觉得 Dan Friedman 的 The Little Schemer (TLS) 是目前最好,最精华的编程入门教材。它的前身叫《The Little Lisper》。很多资深的程序语言专家都是从这本书学会了 Lisp。虽然它叫 "The Little Schemer",但它并不使用 Scheme 所有的功能,而是忽略了上面提到的 Scheme 的毛病,直接进入最关键的主题:递归和它的基本原则。这本书不但很薄,很精辟,而且相对于其他编程书籍非常便宜(在美国才卖 $23)。
《SICP》:The Little Schemer 其实是比较难的读物,所以我建议把它作为下一步精通的读物。Structure and Interpretation of Computer Programs 比较适合作为第一本教材。但是我需要提醒的是,你最多只需要看完前三章。因为从第四章开始,作者开始实现一个 Scheme 解释器,但是作者的实现并不是最好的方式。你可以从别的地方更好的学到这些东西。具体在哪里学,我还没想好(也许我自己写个教学也说不定)。不过也许你可以看完 SICP 第一章之后就可以开始看 TLS。
《A Gentle Introduction to Haskell》:对于 Haskell,我最开头看的是 A Gentle Introduction to Haskell,因为它特别短小。当时我已经会了 Scheme,所以不需要再学习基本的函数式语言的东西。我从这个文档学到的只不过是 Haskell 对于类型和模式匹配的概念。Real World Haskell 是一本流行的教材,但是它试图包罗万象,所以很多地方过于冗长。最根本的函数式编程概念,还是 TLS 讲的透彻。
过度到面向对象语言
那么如果从函数式语言入门,如何过渡到面向对象语言呢?毕竟大部分的公司用的是面向对象语言。如果你真的学会了函数式语言,你真的会发现面向对象语言已经易如反掌。函数式语言的设计比面向对象语言简单和强大很多,而且几乎所有的函数式语言教材(比如 SICP)都会教你如何实现一个面向对象系统。你会深刻的看到面向对象的本质以及它存在的问题,所以你会很容易的搞清楚怎么写面向对象的程序,并且会发现一些窍门来避开它们的局限。你会发现,即使在实际的工作中必须使用面向对象语言,也可以避免面向对象的思维方式,因为面向对象的思想带来的大部分是混乱和冗余。
深入本质和底层
那么是不是完全不需要学习底层呢?当然不是。但是一开头就学习底层硬件,就会被纷繁复杂的硬件设计蒙蔽头脑,看不清楚本质上简单的原理。
在学会高层的语言之后,可以进行语义学和编译原理的学习。简言之,语义学 (semantics) 就是研究程序的符号表示如何对机器产生“意义”,通常语义学的学习包含 lambda calculus 和各种解释器的实现。编译原理 (compilation) 就是研究如何把高级语言翻译成低级的机器指令。编译原理其实包含了计算机的组成原理,比如二进制的构造和算术,处理器的结构,内存寻址等等。但是结合了语义学和编译原理来学习这些东西,会事半功倍。因为你会直观的看到为什么现在的计算机系统会设计成这个样子:为什么处理器里面有寄存器(register),为什么需要堆栈(stack),为什么需要堆(heap),它们的本质是什么。这些甚至是很多硬件设计者都不明白的问题,所以它们的硬件里经常含有一些没必要的东西。因为他们不理解语义,所以经常不明白他们的硬件到底需要哪些部件和指令。但是从高层语义来解释它们,就会揭示出它们的本质,从而可以让你明白如何设计出更加优雅和高效的硬件。
这就是为什么一些程序语言专家后来也开始设计硬件。比如 Haskell 的创始人之一 Lennart Augustsson,后来设计了
BlueSpec,一种高级的硬件描述语言,可以 100% 的合成 (synthesis) 为硬件电路。Scheme 也被广泛的使用在硬件设计中,比如 Motorola,Cisco 和曾经的 Transmeta,它们的芯片设计里面含有很多 Scheme 程序。
这基本上就是我对学习程序语言的初步建议。
本文地址:,欢迎访问原出处。
不打个分吗?
转载随意,但请带上本文地址:
如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 。
大家都在看
现代魔法研究协会欢迎你
阅读一百本计算机著作吧,少年
弗雷德里克·布鲁克斯 (作者), 汪颖 (译者)
《人月神话》原文:The Mythical Man-Month: The Essays on Software Engineering, 2nd ed.在软件领域,很少能有像《人月神话》一样具有深远影响力并且畅销不衰的著作。Brooks博士为人们管理复杂项目提供了最具洞察力的见解。既有很多发人深省的观点,又有大量软件工程的实践。本书内容来自Brooks博士在IBM公司System/360家族和OS/360中的项目管理经验。该书英文原版一经面世,即引起业内人士的强烈反响,后又译为德、法、日、俄中等多种语言,全球销量数百万册。确立了其在行业内的经典地位。
扫一扫,在手机上阅读
栏目最新博文
52,233 views
21,354 views
29,959 views
44,643 views
20,346 views
12,404 views
9,095 views
6,559 views
17,018 views
13,520 views
栏目博文推荐
13,520 views
4,648 views
8,329 views
4,006 views
7,425 views
5,427 views
3,433 views
15,154 views
3,668 views
12,404 views
治疗拖延症最好的方法就是立刻开始。
关于网站与作者
互联网信息太多太杂,各互联网公司不断推送娱乐花边新闻,SNS,微博不断转移我们的注意力。但是,我们的时间和精力却是有限的。这里是互联网浩瀚的海洋中的一座宁静与美丽的小岛,供开发者歇息与静心潜心修炼(愿景)。
“Veda”的本义是知识、启示,希望这里能为开发者提供充足的技术资料。
我的电子邮件gonnsai(,腾讯微博:,欢迎与我联系。永不磨灭的九大尖端编程语言
发表于 14:45|
作者CSDN CODE
摘要:伟大的语言之所以流行是有理由的。它们提供了大量的开源代码,类库以及能使工作更加方便的框架。这些语言多年来被多个项目选作开发语言,并且在它们的擅长领域内变的越来越重要,并且硕果累累。
这些可作为当前流行语言强力替代的语言正在蒸蒸日上,或许你的下个项目正好能用到它。 &&有时候大量的烂大街的主流开发语言也没办法满足你对特定问题的开发需求。有时候你不得不展望未来以期待能出现一门语言:有着良好的语言结构,能提供额外的功能,无需不断调整优化就能使你的代码提高运行速度。这门语言有着更好的稳定性以及良好的的代码结构,能帮你避免写出杂乱的或者错误的代码。这个世界有太多灵巧的语言,例如 C#,Java,Javascript。有些语言可能只有少数拥护者,但是大多数语言,拥有庞大的社区拥护者,这些拥护者有着对这门语言能解决特定领域问题能力的相同的喜爱。可能知道这门语言语法的程序员没有过亿,但是有时候稍稍的变动或许是有价值的,当你学习了一门新的语言,说不定下个项目就能发挥用处。以下的九门语言应该列在每一位程序眼的读书列表中。它们可能并不适合每个工程,因为大多数语言都是针对特定领域的。它们都值得研究和投入精力去学习,说不定哪一天就能派上用场。Erlang:面向实时系统的函数式语言Erlang 最初是由瑞典电信设备制造商爱立信为通信应用(电话交换机)设计的。爱立信的开发者鼓吹 Erlang 的9个9指标的性能,声称 Erlang 能够传输99.9999999%的数据。这时 Erlang 才开始引起人们的关注。Erlang 的秘密是它的函数式设计范例。大部分代码都被强制运行于它的虚拟机中,这很好的避免了其他系统的干扰。函数都在虚拟机内部运行,运行在小的“类似沙箱模式的轻量级进程中”,并且只能通过消息传递相互通讯。你不可能仅仅抓取一个指针就够快速该变指针在栈中的状态。你必须保持在调用层次内部来保证函数状态的一致性。设计上或许有些不妥,但是这样很好的保证了错误向外扩散。这种模式简化了运行逻辑,让运行时代码决定同时能够运行什么任务。并发处理也很容易管理,运行调度程序能够减少上下文切换。Erlang 迷们喜欢吹嘘“在Web服务器上同时运行2000万”处理器“(轻量级进程)。假如你正在构架一个类似移动电话交换机的实时收费系统,但是并没有足够的空间存储数据,那么 Erlang 正好符合你的需求。Go:简单、动态谷歌不是第一家调查集合语言的组织,最终发现语言杂乱,复杂并且效率不高。2009年,谷歌发布了它自己的解决方案:一门静态类型的语言,类似于 C 语言但是包含了其所不具备的特征,它让程序员避免了类型声明和被 malloc 调用锁迷惑。通过 Go 语言,程序员能够受益于塔的简洁、已编译的c语言的结构以及动态脚本语言的的易用性。同时,Sun 和 Apple 也以相同的方式创建了 Java 和 Swift 语言,相应的,Google 做出了一个重要的不同的决定:Go 语言的发明者希望它能足够简单以至于每个程序员都能轻松的掌握。Rob Pike,发明者之一,向 Ars Technica 豪言道:长远来说,通过将事件分开处理,你能够获得更多。因此,Go语言还有一些灵活的特性,泛型,类型继承,断言,只通过干净的简单代码块操作字符串、数字以及哈希表。据报道这门这门语言在巨大谷歌帝国内部被很好的接受,在其它方面也获得了认可,动态语言 Python 和 Ruby 的爱好者接受了编译已编译语言的严密性。假如你想要获得 Google 的青睐,并且需要建立服务器端的业务逻辑,那么 Go 会是一个好的选择。Groovy:提供 Java 的脚本支持Java 世界是异常的灵活。但是你需要仍忍受它”穿个背带裤又要系皮带”的方式,例如,声明,每个变量的类型,分行代表每行结束,类的访问只是返回一个值。但是 Go 语言瞄准了动态语言的吸引人之处并且将它自身紧紧的与 Java 相集成。Groovy 弃置了 Java 乏味的引号和分号方式,提供一种简单的编程习惯,也能用于扩展现有的 Java代码。运行在 jvm 上。不仅仅如此,Groovy 紧紧的月 JavaJAR 相结合,所以你能和好的利用一有的Java 代码。Groovy 运行起来像一门动态类型语言,并且能够访问静态类型 Java 对象的数据。Groovy 程序眼认为他们技术与 Java 程序员,同事也是 Groovy 程序员。基于 Java 代码,能够提供非常多的功能。充分使用 Java 拥有的闭包,操作符重载,多态性。不要忘了使用问号来做空指针的判断的简易性,这比使用 if-then 语句来判断要简单得多。因此,简洁的语法,使程序员敲击键盘次数减少了。谁会不喜欢呢?最后,令所有 Java 程序员羡慕的动态语言的简单特点让他们能够减少工作量,有更多的娱乐时间,但是又不跳出 Java 圈。OCaml:复杂数据层次把戏一些程序员不喜欢声明变量,于是他们创建了动态语言。其他人喜欢声明一个变量的特定类型,integer,string 或者是 object。对于他们来说,大多胡编译型语言都对类型声明提供了支持。这是一些喜欢详细声明变量层次类型的,甚至谈到要创建“algebras”(代数)类型。他们想象列表和多种类型的表能用来表示复杂、多层次的数据。他们提到了多态,模式匹配原型以及数据封装。这只会他们期望的复杂的,高结构化类型、原型以及原原型世界的基础。对于他们,OCaml,一门有多个编程社区为了让前述想法被广泛接受而共同努力的语言。OCaml 提供类对象的支持,自动内存管理以及跨平台。甚至苹果App商店也提供了 OCaml 的 App 支持。OCaml 的理想的工程可能是建立一个符号数学网站来教授代数。CoffeeScript:使 JavaScript 更简洁技术角度来说,CoffeeScript 并不是一门语言。这是一个将你写的代码转换 Javascript 的预处理器。但是它看起来有所与众不同,因为它缺少大量的标点符号。你可以人为他是 Ruby 或者 Python,尽管内部表现像 Javascript。当封号厌恶者被强制用浏览器支持的 Javascript 编程的时候,Coffeescript 开始流行了。改变浏览器工作的脚本语言是不切实际的,于是他们写了他们自己的预处理。结果是程序员们能够写干净的嗲吗并且让 CoffeeScript 将那些代码转译成各种符号的 Javascript 语言指令来操控浏览器。少了分号紧紧支持开始。通过 CoffeeScript,你甚至不需要通过var来声明变量。声明函数也不需要function 关键字或者大括号。事实上,大括号在 CoffeeScript 中也不太被使用。代码是如此的简洁,以至于相比于哥特式教堂,它看起来像现代主义建筑物。这就是为什么很多新的 Javascript 框架通常是用 CoffeeScript 写的然后编译成 Javascript。Scala:JVM上的函数式编程假如你想要让你的代码有面向对象的清晰层次结构又喜欢函数型编程模式,那你有很多选择。假如你熟悉 Java,Scala 会是你的一个选择。Scala 运行在 JVM 上,并将所有的清晰的函数式编程的约束转变成 Java 支持的语法以及联接到具体的 JAR 文件。假如那些额外的 JAR 中有副作用和其他不可避免的令人讨厌的头痛代码,那么使用Scala 刚刚适合业务场景,你的代码会变得很清晰。Scala 是静态类型的。编译器负责在编译时推断出具体类型,对象类型和原始类型没有区别,因为Scala 想让每一个对象都继承自 Any。Scala 的语法比 Java 更加简洁。Scala 程序员称之为“低礼节”。你可以把驼峰式命名方式遗留在 Java 世界了。Scala 提供了很多函数型语言的特征,例如懒初始化,尾递归,常量。但是为了能在 JVM 中运行,做了适当的修改。基本的原类型或者列表变量(像lists和哈希表),可以是可变或者不可变的。尾递归通过简单的例子运行,而不是必须通过详细声明的可变递归。以上是 Scala 的全部实现思想,但是因为需要运行在 JVM 上,具体实现会有所限制。Scala 能够所有 Java 平台上运行,能很好的与已存在的开源 Java 代码混用。这对于许多实践性问题是一种权衡。 & &假如你需要将数据放在一千个处理器的集群中处理,并且有一堆遗留的 Java 代码,那么 Scala 是一个很好的解决方案。Dart:不像 JavaScript 的 JavaScript流行并不是被吹捧出来的。可能有越来越多领域使用到了 JavaScript,“事君数,斯辱矣;朋友数,斯疏矣”,有时候太过于亲近反而会导致疏远,疏远了然后就开始寻找替代。Dart 是 Google 出品的一门适用于 Web 浏览器端的新语言。Dart 并没有从 JavaScript 基本概念中脱离出来。它工作在浏览器中,操作所有的 DIV 和我们所见的Web 对象。Dart 的作者仅仅只是为了清除 JavaScript 中所有恼人的部分,使之变得更简洁。底层结构并没有太大的变化。因为他们希望将 Dart 代码转成 Javascript 来提高运行速度。高亮可能在许多 JavaScript 类库中提供的额外功能。你不需要通过 jQuery 或者其他通用类库来修改部分 HTML 页面。Dart 提供了默认的支持。也许一些熟悉的数据类型以及语法的速记技巧能够少敲几次键盘。Google 通过提供开源的支持大多数主流平台的开源工具来答题推广 Dart。假如你正在建立一个动态的 Web 应用。并且已经对于 JavaScript 厌烦了,Dart 提供了清晰的语法结构来创建有多种 Web 资源数据的 Div 块。Haskell:通用纯函数式编程语言经过超过20年的时间,一直研究函数型编程的学术研究者开发了 Haskell 语言,一门用来表达他们对于副作用的坏处的想法的语言。这是一门更加存粹的表达式函数型语言,通过精细的机制来处理 I/O Channels 和其他不可避免的副作用。其余的代码应该是相当有用的。Haskell 社区相当活跃,那里有很多 Haskell 的变体等着你去探究。有些是单机版的,其他的是通过与像 Java(Jaskell,Frege)或者 Python 那样的主流语言集成的。大多数的名字显示他们来自苏格兰,那里是 Haskell 研究,或者是哲学家/逻辑学家(他们是许多 Haskell 思想的启蒙者)的温床。假如你认为你的数据结构和类型太复杂了,你可以考虑用 Haskell。Julia:给Python界带来了新的消息科学计算领域有一群 Python 的爱好者,享受 Python 带来的简单语法以及能够避免陷入乱用指针和字节的细节中的自由自在。除了所有的优点,Python 通常在科学计算中处理大数据所表现的令人发狂的运行速度一值是一个诟病。为了提高运行速度,很多科学家转而使用c语言来编写核心的运行代码。但是这带来了新的问题,用两种语言写的程序很难修改或者扩展。Julia 是这种复杂问题的一种解决方案。它的作者带来了零 Python 程序员欣赏的干净语法并且做了稍稍修改使之能够在后台编译代码。通过这种方式,你能够像 Python 那样打开个记事本或者命令行来编码,但是你写的任何代码都会被即时编译。Julia 真是非常了不起的语言。它提供了非常强大的类型分析引擎能够帮助优化代码。假如你喜欢元编程,这门语言提供了足够的扩展接口。它最大的附加价值是通过集群发布并行算法的简单机制。其内置了大量的数学算法库用来做数据分析。最好的消息应该是它的运行速度。它的许多基本标准的运行速度是 Python 的30倍,甚至比 C 语言还快一点,假如你需要处理大量数据并且喜欢 Python 的语法,那么你最好快去学学 Julia 吧。(原文:,译者:)
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章}

我要回帖

更多关于 精通一门编程语言 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信