Elixir 程式设计


Elixir 程式设计

文章插图
Elixir 程式设计【Elixir 程式设计】《Elixir 程式设计》是2016年3月电子工业出版社出版的图书,作者是【美】Dave Thomas(大卫·托马斯) 。
基本介绍书名:Elixir程式设计
作者:【美】Dave Thomas(大卫·托马斯)
译者:杜万 黄明信 
ISBN:978-7-121-28264-5
页数:340
定价:75.00元 
出版社:电子工业出版社
出版时间:2016年3月
开本:16
内容简介《Elixir 程式设计》作者就是15 年前编写了Programming Ruby,将Ruby 带入大众视野的Dave Thomas 。这一次他延续了一贯的写作风格,以一个拥有面向对象的开发经历但并未接触过函式式编程的开发者的角度切入,循序渐进地带领读者进入 Elixir 的奇妙世界 。通过一步步的实验探索,引导读者逐步跳出已有的编程思维模式,以全新的函式式编程方式来思考及寻找解决实际问题的办法 。然而本书并不像Programming Ruby 那样面面俱到,而是给读者讲述基本的Elixir 语法和编程思想,同时提供许多有用的资源,启发读者继续深入探索 。这也是学习一门新语言的乐趣所在 。如果你对函式式编程有兴趣,或者你正在苦苦寻求一种高效的并发编程的方法,Elixir 可以作为入门之选,值得一试 。编辑推荐学习函式式编程的入门好书用一种更优雅、更高效的方式开发高性能的并发软体目录第1 章 接受现实 1编程时应该关注数据转换 1藉助管道来组合转换 2函式是数据转换器 3安装 Elixir 3运行 Elixir 4iex—互动式 Elixir 4编译和运行 8对阅读本书的建议 9练习 9换一种方式思考 10第一部分 常规编程第2 章 模式匹配 12赋值:并非如你所料 12更複杂的匹配 13轮到你了15用_(下画线)忽略匹配值 15每次匹配变数仅绑定一次 15轮到你了17从另一个角度来看等号 17第3 章 不可变性 18你已经拥有了(一些)不可变数据 18不可变的数据才是已知的 19不可变性对性能的影响 20複製数据20垃圾回收20用不可变数据编写程式 21第4 章 Elixir 基础 22内置类型 22值类型 23整数 23浮点数 23原子 24区间 24正则表达式 24系统类型 25PID 和连线埠 25引用 25收集类型 26元组 26列表 27散列表 28二进制型29命名、源档案、约定、运算符和其他 30真值 30运算符 31小结 32第5 章 匿名函式 33函式和模式匹配 34轮到你了35一个函式,多个函式体 35编写更长的代码 36轮到你了37能返回函式的函式 37记住原始环境的函式 38参数化函式 39轮到你了39将函式作为参数来传递 40& 运算符 40轮到你了42函式是核心 42第6 章 模组与命名函式 43编译模组 43函式体是代码块 44轮到你了45函式调用与模式匹配 45轮到你了48哨兵子句 48哨兵子句的限制 49默认参数 50轮到你了53私有函式 53|> ——美妙的管道运算符 54模组 55模组指令57import 指令 57alias 指令 58require 指令 58模组属性 58模组名:Elixir、Erlang 和原子类型 59调用 Erlang 的库函式 60寻找函式馆 60轮到你了61第7 章 列表与递归 62头部和尾部 62使用头部和尾部来处理列表 63iex 如何显示列表 64使用头部和尾部来构造列表 66创建映射函式 67在递归过程中跟蹤值 68轮到你了69生成求和函式 69轮到你了70更複杂的列表模式 71列表的列表 71轮到你了74List 模组实战 75与列表友好相处 76第8 章 字典:散列表、散列字典、关键字列表、集合与结构体 77如何在散列表、散列字典和关键字列表之间做选择 77字典 78模式匹配和更新散列表 79模式匹配不能绑定键 81更新散列表 82散列表与结构体 82访问结构体的另一种方式 84嵌套字典结构 85嵌套访问器和非结构体 86动态(运行时)嵌套访问器 87集合 88能力越大,诱惑越大 89第9 章 番外篇—类型是什幺 90第10 章 处理收集—Enum 与Stream 92Enum——处理收集 92关于排序的说明 95轮到你了96Stream——延迟处理的枚举类型 96流是可组合的枚举器 97无限流 99自定义流99流在实际中的套用 104Collectable 协定 104 推导式 105推导式也可以处理二进制位 106作用域与推导式 107推导式的返回值 107轮到你了108感动过往的神 109第11 章 字元串与二进制型 110字元串字面量 110Heredoc 111魔术符 112“字元串”这个名称 113单引号字元串——字元编码列表 114轮到你了116二进制型 117双引号字元串是二进制型 118字元串与Elixir 库 118轮到你了124二进制型与模式匹配 124用二进制型来处理字元串 124轮到你了125熟悉却又陌生 126第12 章 控制流 127if 与 unless 127cond 128case 131抛出异常 133包含异常的设计 133四两拨千斤 134轮到你了134第13 章 组织项目 136项目:从 GitHub 获取 issue 136我们的代码将如何工作 137任务:用mix 来创建我们的新项目 137创建项目树 138转换:解析命令行 140进阶:编写一些基本的测试 142轮到你了144转换:从 GitHub 获取数据 144任务:使用外部库 145寻找库 146为项目添加库 146轮到你了148回到转换148转换:转换回响内容 151不在 hex 里的依赖项 152应用程式配置 152转换:为数据排序 153转换:取前n 条 155轮到你了156转换:格式化表格 156任务:创建命令行可执行程式 159任务:添加日誌 161任务:测试代码注释 163任务:创建项目文档 167使用转换数据的方法来编写代码 169轮到你了170第14 章 运用多进程 172简单的进程 173在进程间传送讯息 174处理多条讯息 175递归、循环与栈 178进程开销 178轮到你了181进程何时结束 182关联两个进程 183监控进程185轮到你了186并行map——Erlang 版本的“Hello, World” 186轮到你了187斐波那契数伺服器 188任务调度器 189轮到你了192代理——一个难题 192以进程的方式来思考 194第15 章 节点——分散式服务的关键 195 命名节点 195轮到你了197节点、cookie 与安全 198给你的进程命名 199何时给进程命名 202轮到你了202I/O、PID 与节点 203轮到你了204节点是分散式的基础 205第16 章 OTP:伺服器 206一些 OTP 的定义 206OTP 伺服器 207状态和单个伺服器 207我们的第一个 OTP 伺服器 208轮到你了210单向调用210跟蹤伺服器的执行情况 212轮到你了214GenServer 回调函式 214给进程命名 216整理接口 217轮到你了218第17 章 OTP:应用程式监视器 220应用程式监视器与工作进程 220轮到你了223管理重启前后的进程状态 223应用程式监视器是可靠性的核心 229轮到你了229第18 章 OTP:应用程式 230这不是传统的应用程式 230应用程式规範档案 231将Sequence 程式转变为OTP 应用程式 231关于套用参数的更多信息 234监视是可靠性的基础 234轮到你了235热代码交换 235OTP 很大——难以置信的大 241轮到你了241第19 章 任务与代理 242任务 242任务与监视 243代理 244更大的例子 246使其分散式运行 248使用代理与任务,还是GenServer 249第三部分 更高级的Elixir第20 章 宏与代码求值 252实现if 语句 252宏注入代码 254装载次序255quote 函式 256将内部表示作为代码使用 256unquote 函式 258展开列表——unquote_splicing 259回到我们的myif 宏 260轮到你了261使用绑定来注入值 261宏是卫生的 263执行代码片段的其他方法 264宏与运算符 265深入研究 266更进一步 266轮到你了267第21 章 连线多个模组:行为与use 268行为 268定义行为268声明行为269use 与 __using__ 270放到一起——跟蹤方法调用 270使用use 275轮到你了275第22 章 协定——多态函式 277定义协定 277实现协定 278 可用的类型 279轮到你了280协定和结构体 280内置协定:Access 281内置协定:Enumerable 282内置协定:String.Chars 285内置协定:Inspect 286协定就是多态 288轮到你了288第23 章 更酷的玩意儿 290自定义魔术符 290获取选项292轮到你了293多套用的 umbrella 项目 294创建 umbrella 项目 295创建子项目 295LineSigil 项目 296Evaluator 项目 296连线子项目 297别急!还有更多炫酷的玩意儿! 299附录A 异常:raise 与try,catch 与throw 300附录B 类型规範与类型检查 306精彩节摘推荐序最开始杜万说请我为他翻译的Elixir 的新书写一篇序,我一头雾水,因为完全没有听说过“Elixir”这个词,我甚至到现在都不知道这个单词应该怎幺读,虽然我已经读完了全书 。是的,刚才那个句子很长,不好读,然而它的逻辑是正确的 。这跟我初步了解Elixir 的感觉差不多,不好理解,但逻辑是正确的 。虽然我现在很少写代码了,但是作为一个曾经写了十几年代码的人,本书讲述的内容,特别是Elixir 的思想很是让我震撼 。我必须承认我并没有彻底理解这本书,很多的细节没有时间去详细实践,但就我不深的理解,已经体会到了这种基于进程的编程思想,以及它带来的变革 。在我中学开始学习编程的时候,用的是 Pascal 。我知道数据结构、算法,我会做题,然而我对软体工程一无所知,不知道如何编写一个完整的套用 。后来大学的时候学习Java,才知道 Pascal 是一种面向过程的语言,Java 是面向对象的语言 。然而我花了很久才理解了什幺叫作“对象”,以及什幺叫作面向对象的编程 。我清晰地记得 Java 课的第一次作业是编写一个计算器程式 。整个程式我只有一个 Java 档案,所有的代码都在这个档案中,活生生用 Java 语言写了一个 Pascal 程式 。编程思想的转变是困难的 。我在读这本书的时候,再一次感受到了编程思想的转变,从面向对象到面向进程 。原本在 Java 中非常複杂的多执行绪、分散式处理方式在 Elixir 中变得无比简单,这也是 Elixir 在现代 IT 系统中的价值:最大化CPU 的处理能力 。大概一年前,我有一个朋友说他最近在疯狂地研究 Erlang(一种跟 Elixir 接近的语言),他打算说服公司的领导用 Erlang 重做一个系统 。当时我觉得他疯了,我对 Erlang不了解,只知道这是一种很奇怪、很小众的程式语言,现在我可以理解那个朋友当时的想法了,他一定有一种脑洞大开的感觉!不论你现在是做 APP 开发,传统 Web 开发,还是在中国大红大紫的微信开发,都应该读一读此书,它一定会让你眼前一亮 。没有最好的程式语言,只有最合适的程式语言 。随着硬体的不断发展,一定会有很多不同于过去常见的编程思想和语言出现,以适应最新的硬体 。也许本书的内容不能在你的工作中用到,但这不重要,重要的是思想的碰撞带来的愉悦,以及碰撞后留下的那些思考 。张海龙,Coding CEO2016 年1 月19 日·深圳译者序还记得第一次得知 Elixir 是 Coding 的冒泡1上 mingshun2 的一句牢骚:“不要咖啡,不要大象,不要蟒蛇,不要红宝石,只要万金油” 。这句开发者的唠叨,吸引了我的注意 。显然咖啡表示 Java,蟒蛇表示 Python,红宝石表示 Ruby,大象呢?“最好的程式语言,PHP”,一个同事提示道 。Google 搜寻了一下,果然 PHP 的 logo 是一头大象 。“那幺万金油呢?”我追问道 。同事也一副“什幺鬼”的表情,凑过来一起Google 了一番,才知道万金油是 Erlang 虚拟机上的一门语言,相当于 Scala 之于 Java 虚拟机,英文名字叫Elixir 。这是一门全新的语言,有一些新奇的特性,于我小有触动 。后来从 mingshun 那里了解到Programming Elixir 写得不错,国内还没有翻译版本 。于是我就开始张罗和 mingshun 合作翻译 。先找博文视点的编辑许艳与外方谈妥了翻译着作权,试译两章,然后很快签了契约开始动工 。初稿阶段比较顺利,我们把每一章编写成独立 Markdown 档案,还写了一个脚本,把Markdown 格式自动转换成 Word 格式 。我们把译稿放在 Coding 的代码仓库里,每译完一章就提交一个合併请求给另一个 Peer Review 。排版以后就没那幺顺畅了,新发现的问题标注在PDF 档案上,一个人先审,另一个人候着,不容易并行执行 。之前了解过原书出版社 Pragmatic Bookshelf 有一套工具可以由源档案生成多种格式的目标档案 。有了这套工具写书就像写代码,一次编写,无须排版 。写了封邮件向 Pragmatic Bookshelf 出版社问询,对方称暂时没有对译者开放工具 。此时深感工具之重要,对于创作和翻译而言,工具就是生产力 。写代码也一样,良好的工具链可以极大地提高生产效率,这也是 Coding 推出的一系列云端开发工具的价值所在 。在翻译的过程中得到了很多人的帮助,首先要感谢合译者黄明信,是你把 Elixir 这幺美妙的语言带给了我,感谢你一次次在翻译过程中帮我解惑,帮我字斟句酌;感谢责任编辑许艳,感谢你在整个过程的付出,感谢你细緻地审稿,从一次次反馈中感受到了你编辑工作的严谨;感谢同事杨臻,在一些拿捏不準的地方,帮我提了许多建议;感谢所有帮助过我的人 。杜万2015 年 1 月 3 日于上海遇见 Elixir 可能是一种缘分吧!我比较喜欢管它叫“万金油”,但并不代表它就是万能的,毕竟世界上没有完美的东西 。Elixir 继承了 Erlang 在构建分散式系统上的优点,并通过添加众多现代程式语言的特性来提升语言的表达能力 。如果说 Erlang 是并发编程的领路者,那幺 Elixir 就是你一路跑来在沿途看到的美好风景,它会让你的编码旅程更精彩 。翻译这本书是为了让更多人能了解 Elixir 。无论你是否会在项目中使用它,都值得你去“玩”一下,体验一下新思维 。现代程式语言的实用性不局限于它的运行效率,还体现在语言的表达能力及对基础设施的抽象能力上 。在我看来,写代码如同文学创作,不仅要把你的想法準确地传达给机器,更重要的是让读代码的人有种清风扑面而来的快感 。这本书与Programming Ruby 是同一位作者,他的写作风格是技术作者中少有的,措辞生动,引经据典,颇富文采,奈何中西文化有别,本人又才疏学浅,未能将原作者的想法传神地表达出来 。希望各位读者多多包涵 。非常感谢在翻译过程帮助过我的同事们,特别是本书的另一位译者,杜万 。由于是第一次翻译,很多工作都不懂如何开展,加上又是个急性子,经常会为些小事情发牢骚 。感谢他对我的包容,每当想放弃的时候他都在一旁鼓励 。同时还要感谢出版社的工作人员,正因为他们在整个过程中的辛劳付出,本书才得以顺利出版 。黄明信2015 年 1 月 4 日于湛江媒体评论Dave Thomas 再一次做到了:《Elixir 程式设计》成为了每本编程书籍都渴望与之比肩的目标 。它不是简单地教授语法和举几个刻板的例子,而是引导你如何以Elixir 的方式思考 。Bruce Tateicanmakeitbetter.com公司CTO,技术作家在《Elixir 程式设计》里,David 出色地介绍了函式式编程,他以一种有趣、实用、充满灵感的方式教我们重新思考如何用不同的方法来设计程式 。随着阅读的深入,你会不时会心一笑,因为你发现 Elixir 的某方面可以让你用一种新的、更优雅的方式来解决问题,而且这种方式非常自然和直观,我们这些编程人员必须马上套用起来才行 。这本书详细地介绍了 Elixir 及其工具,旨在使开发过程更加流畅和富有成效 。Dave 解释了 Erlang 运行时系统的核心部件,如分散式、并发和容错,它们为 Elixir 提供了编写可扩展、适应性强的应用程式的能力 。Alexei Sholik顺序编程的时代已经过去,如今高性能、可扩展和容错的软体都是并发的 。Elixir 是这个全新世界里的关键角色,它将 Erlang 和 OTP 的能力带给更广泛的客群 。阅读本书吧,为迎接软体开发新时代开个好头 。Paul Butcher《七周七并发模型》的作者就像镐头书之于 Ruby,这本书是 Elixir 的事实标準 。Dave 以他无可挑剔的风格,全面介绍了Elixir 语言的各方面,包括数据结构、宏、OTP,甚至 Dialyzer 。阅读本书是一种享受,因为它带领读者学习 Elixir,并带领他们参与编写函式式程式的整个思维过程 。如果你想快速掌握 Elixir 语言,《Elixir 程式设计》是你的最佳选择 。Jim Freeze首届世界Elixir 会议的组织者这无疑将成为 Elixir 的镐头书 。……Dave 很兴奋地带领读者进入迷人的 Elixir 世界 。对于对 Elixir 感兴趣的每一位程式设计师而言,本书值得拥有 。Dan Kozlowski《Elixir 程式设计》是Dave Thomas 的另一佳作 。在此之前我尝试的几个函式式程式语言都让我备受挫折 。你能感觉到Dave 的热情和在每一章节使用该语言时的喜悦 。他会让你以从未想到过的方式来思考解决问题的办法 。这本书让我彻底改变了在思考各种语言编程的改进时的方式 。Richard Bishop我真的很享受阅读这本书 。它不只是一股脑儿地介绍一些语法或特性;总的来说,我认为它对 Elixir 和函式式编程做了非常周到的介绍 。Cody Russe前言我对于计算机硬体的变化给编程方式带来的影响一直很感兴趣 。几十年前,记忆体是非常紧缺的资源 。那时,对软体而言,接管一块记忆体并在需要的时候修改其中的内容也是非常合乎情理的 。然而,将这块记忆体分配出去,当不再需要它的时候将其清理乾净,则是一件很容易出错的工作 。某些记忆体永远得不到释放;有时记忆体被分配到另一个正在被使用的结构数据之上而导致程式出错 。当时,垃圾回收已经是众所周知的技术,但我们需要更快的CPU 才能在日常的软体中套用此项技术,把我们从手动管理记忆体的苦役中解放出来 。好在这已经成为现实——大多数语言现在都支持垃圾回收 。时至今日,相似的情况再次发生 。儘管CPU 没有变得更快,但是我们的计算机的CPU 核心越来越多 。这意味着,如果软体要最大化其对机器的利用率,就要儘可能使用更多的CPU 核心 。这种情况正好与我们现在编写软体的方法有所冲突 。事实上,当使用多核的时候,修改记忆体状态确实会拖慢软体的运行 。如果有四个CPU 核心尝试访问和操作同一块记忆体,它们就会相互阻塞 。除非採用某种同步机制,否则这样很可能会导致记忆体崩溃 。很快我就发现使用同步既费劲,还容易出错,而且烦人,它还会损失性能 。突然,我意识到不能将接下来几年的职业生涯花费在这种编写软体的方式上,所以我开始学习新的语言和技术 。在这个探索的过程中,我迷上了 Erlang 虚拟机及其生态圈 。在 Erlang 虚拟机里,所有代码都运行在微型的并发进程中,每个进程拥有自己的状态 。进程通过讯息进行通信 。并且因为所有通信都是通过讯息传递来进行的,所以虚拟机能够透明地处理同一个网路中不同机器的讯息交换,这使它成为构建分散式软体的绝佳环境!然而,我感觉在 Erlang 生态圈中依然存在某些空白 。我在日常工作中所需要一些功能,Erlang 生态圈没有给予很好的支持,如元编程、多态以及优秀的工具等 。Elixir 就是从这一需求中诞生的 。Elixir 是注重实用的函式式程式语言 。它遵从函式式编程的基础,同时注重提高开发者的生产力 。并发是 Elixir 程式的精髓 。正如垃圾回收将开发者从记忆体管理的枷锁中解放出来,Elixir 就是要将你从陈旧的并发机制中解放出来,让你能快乐地编写并发代码 。函式式程式语言让我们以函式的方式来思考问题,而函式仅转换数据 。这种数据转换从来不会修改数据 。相反,对函式的每一次使用可能都会为这个数据创建一个新版本 。这样就大大地减少了数据同步机制的使用 。Elixir 还给开发者提供强大的宏 。Elixir 代码也被看作是数据,而且可以通过宏来处理,就像Elixir 中的其他任何值一样 。最终,我相信面向对象的程式设计师会在 Elixir 中找到很多他们认为编写优秀软体所需的机制,比如多态 。所有这些都由Erlang 虚拟机提供支持,它已经有20 年历史,从零开始开发以支持健壮的并发分散式软体 。Elixir 和Erlang 虚拟机将改变你编写软体的方式,并为你应对未来的编程问题做好準备 。José ValimElixir 的作者2014 年 10 月于荷兰 Tenczynek