这篇文章主要介绍了Erlang初学:Erlang的一些特点和个人理解总结,本文总结了函数式编程、一切都是常量、轻量进程、进程端口映射及典型缺点等内容,需要的朋友可以参考下

我对 Erlang 编程理念的理解:以分布式架构师的角度写代码。

函数式编程

Erlang 里面的函数是数学里面的函数:必须有返回值。 只要是函数必然有返回值,函数是一个过程,以英文的句号为函数结束符。 函数结束之前的表达式就是该函数的返回值。 所以这也是在 Erlang 里面的函数不会看到任何 return 语句的原因。 C++ 等其他语言的函数和函数之前可以通过共享变量来实现消息传递。 Erlang 里面的函数不可以,消息的传递通过函数的传入和传出。 也只是为什么 Erlang 号称天生之处并行处理的原因, 因为他们不共享变量,也就不需要加锁。

很多人听到函数式编程都会觉得高大上或者晦涩难懂。 因为函数是编程没有 for 循环语句, 但是在我看来,关键在于会使用【列表推倒】和【尾递归】来进行循环遍历。 说到函数式编程就会拿快速排序说事,下面这个示例是 Erlang 版本的快速排序:

代码如下:
  1. -module(sort).
  1. -export([qsort/1]).
  1. qsort([]) -> [];
  2. qsort([Pivot | T]) ->
  3.     qsort([X || X <- T, X < Pivot]
  4.          ++ [Pivot] ++
  5.          qsort([X || X <- T, X >= Pivot]).

非常简洁,[Pivot | T] 就是拿列表的第一个元素当快排中的 Pivot 。

代码如下:
  1. [X || X <- T, X < Pivot]

上式就是【列表推导】, 含义就是找出列表 T 中所有元素小于 Pivot 中的元素组成一个新的列表。 不过,这个例子显然性能不高,只是一个示例。

很多人一直在鼓吹函数式语言马上就要迎来朝阳, 但是在我看来,函数式编程永远只能是小众语言, 这就像当年的 lisp machine ,被鼓吹的天花乱坠还是夭折了。 现在主流的计算机架构都是冯诺依曼体系的,并不是最适合函数式语言的生存土壤。

一切都是常量

没有变量,也就没有通过变量共享状态导致的资源竞争,也就不需要加锁。 任何状态的变化都是通过函数的输入输出来进行改变, 轻量级进程的状态变化也是靠消息传递(函数的输入输出)来实现。 这也是为什么有人说函数式编程适合高并发的原因,因为他们没有变量, 一切都是常量。

轻量进程

Erlang 里面有 spawn 函数,可以快速的创建一个 process , 这里的 process 不是操作系统的进程,而是 Erlang 自己的轻量进程。 Erlang 轻量到超乎你想象, 构建 kv 数据库的时候,甚至可以对不同的 key 分配给不同的进程。 而且进程的表示单位是 Pid ,只要知道进程的 Pid, 哪怕该进程是在别的机器上面,都可以很轻易的发送给它。 原因是 Erlang 的【天生自带RPC通信】和【自带端口映射】

天生自带RPC通信

代码如下:
  1. ToPid ! Data

ToPid 是接受方进程的id , Data 可以是 Erlang 的任何类型,比如

代码如下:
  1. Pid ! {name, "wp.iirii.com"}.

也就是可以直接把任何数据结构当成消息发送,天生自带 RPC 通信。 (虽然本来 RPC 的含义是“远程过程调用”,不过其实反正就是帮你序列化了数据结构,Erlang 的 ! 操作符也是如此。)

进程端口映射

节点之间发消息在代码里面的表示也还是

代码如下:
  1. ToPid ! Data

也就是在写代码的时候,根本不用考虑该进程是在哪台机器上面, 无论是本 Erlang 进程(这里的进程是操作系统级别的进程,不是 Erlang 的轻量进程) 内, 还是其他机器的进程,都不用管。 这是因为有 epmd 的存在。

Epmd是Erlang Port Mapper Daemon的缩写,在Erlang集群中相当于dns的作用,供给节点名称到端口的查询办事,epmd绑定在总所周知的4369端口上。

有了 epmd ,写分布式程序就好像写单机程序一样简单。

严密的模块化管理

Erlang 的模块类似 C++ 中的 namespace(命名空间),但是比命名空间更利于高效的软件工程管理。

在 Erlang 项目源码中处处可见如下代码。

代码如下:
  1. -module(my_app).
  2. -export([start/2, stop/1]).

-module 指明模块名,-export 指明导出的函数。 未被导出的函数都无法被外界调用。 从软件工程上看的话,这样使得模块功能和使用方法更加清晰。 使用者只需要关心如何 -export 里面的函数即可。 相比较之下 C++ 对这方面特别不规范,而 Java 通过对类声明为 public class 指明可以被外界使用, Node.js 也是使用 export 来显示声明可以被外界使用的函数。

行为模式

代码如下:
  1. -module(ecomet_app).
  1. -behaviour(application).
  1. %% comment: Application callbacks
  2. -export([start/2, stop/1]).
  3. -behavior(application).

Erlang/otp 里面的【行为模式】概念等价于 OOP 里面的接口概念。 上面代码示例的意思就是该模块(ecomet_app)遵守的行为模式是(application)。 刚行为模式需要实现的两个接口函数就是 -export([start/2, stop/1]). 。

另一个示例如下是遵守监督者(supervisor)行为模式, 实现的一个接口函数是 -export([init/1]). 。

代码如下:
  1. -module(ecomet_sup).
  1. -behaviour(supervisor).
  1. %% Supervisor callbacks
  2. -export([init/1]).

监督者机制

Erlang/otp 的天生分布式特性在监督机制里面体现的很好, 每一个 otp 应用启动的时候,都是启动监督者(supervisor)和工作者(worker)。 他们的关系是树形结构,每个工作者的上级都会有监督者, 每个监督者的上级也可能有监督者。 当工作者异常退出的时候,监督者会根据相应的参数决定是否对工作者进行重启。 如果重启失败的话监督者也会退出,而更加上层的监督者收到信号后会对他们进行重启等处理。 这个监督者机制非常好理解,其实就是 OOP 编程里面的 try … catch 异常处理机制。 当出现异常的时候一层一层的往上抛出,直到有人重启。

otp平台

Erlang 最强大的地方也是最让我感觉难学的地方,就是它的 otp 平台。 各种行为模式, 让我感觉就像多年以前学习 MFC 的时候, 感觉很强大,但是却总是感觉自己被按死在一条特定的轨道上面奔跑, 有种不自由的疲惫感。

代码热切换

热切换也叫热升级,大部分情况下,如果需要对 C++/Java 程序进程版本升级, 则需要重启进程。 Erlang 支持热切换的意思就是可以在运行的时候进行代码升级。 升级过程不影响进程的运行, 而且在过渡阶段新旧版本还可以共存。 是不是碉堡了。这个功能对于那些需要 7×24 高可用的服务来说简直就是爽爆了。

Erlang 进程本身可以通过一个类似“后门”的控制台 erl 来实时的查看状态, 甚至直接使用控制台来修改配置等,非常方便,这对于大部分其他语言来说, 简直就是黑魔法般神奇的存在。

典型缺点

1.文档太少,出现问题搜索出来的答案也少。
2.Erlang 人才稀缺,招聘不易。
3.动态语言最典型的就是调试不易。
4.上手门槛较高。

Erlang初学的更多相关文章

  1. erlang工作前新手学习指引路线

    Erlang学习总结,新手指引 要具体的写erlang入门技术网上有非常多,我写的肯定没有那些大牛写的好,自己也实习了快一个月,也做一个总结,给后erlang初学兴趣者提供些拙见吧 第一步搭建学习环境 ...

  2. [Erlang 0119] Erlang OTP 源码阅读指引

      上周Erlang讨论群里面提到lists的++实现,争论大多基于猜测,其实打开代码看一下就都明了.贴出代码截图后有同学问这代码是哪里找的?   "代码去哪里找?",关于Erla ...

  3. notepad++ erlang开发环境设置

    初学erlang 网上有使用eclipse的,有使用emacs的,尝试了一下, 感觉太麻烦,来试试notepad++吧. 有什么新使用方法会再更新上来,for you for me. 1.语法高亮: ...

  4. Erlang语言学习入门

    这是一个命令行程序,可以直接在里面输入表达式进行计算,例如来一个简单的: Erlang R15B01 (erts-5.9.1) [smp:4:4] [async-threads:0] Eshell V ...

  5. 理解Erlang/OTP - Application

    http://www.cnblogs.com/me-sa/archive/2011/12/27/erlang0025.html 1>application:start(log4erl). 我们就 ...

  6. DDD初学指南

    去年就打算总结一下,结果新换的工作特别忙,就迟迟没有认真动手.主要内容是很多初学DDD甚至于学习很长时间的同学没有弄明白DDD是什么,适合什么情况.这世界上没有银弹,抛开了适合的场景孤立的去研究DDD ...

  7. gulp初学

    原文地址:gulp初学 至于gulp与grunt的区别,用过的人都略知一二,总的来说就是2点: 1.gulp的gulpfile.js  配置简单而且更容易阅读和维护.之所以如此,是因为它们的工作方式不 ...

  8. 初学seaJs模块化开发,利用grunt打包,减少http请求

    原文地址:初学seaJs模块化开发,利用grunt打包,减少http请求 未压缩合并的演示地址:demo2 学习seaJs的模块化开发,适合对seajs基础有所了解的同学看,目录结构 js — —di ...

  9. [Erlang 0129] Erlang 杂记 VI

    把之前阅读资料的时候记下的东西,整理了一下. Adding special-purpose processor support to the Erlang VM   P23 简单介绍了Erlang C ...

随机推荐

  1. ionic的tabs

    <ion-tabs class="tabs-icon-top/bottom(决定这个tabs是置于上面还是底部)  tabs-color-active-positive(图标与字体色) ...

  2. 手把手教你配置UltraEdit对Oracle的PLSQL着色

    http://hi.baidu.com/kingbridge/blog/item/94e225ad5fad4b194b36d60d.html   UltraEdit-32 12.1版本配置默认文件显示 ...

  3. iOS开发ARC内存管理技术要点

    本文来源于我个人的ARC学习笔记,旨在通过简明扼要的方式总结出iOS开发中ARC(Automatic Reference Counting,自动引用计数)内存管理技术的要点,所以不会涉及全部细节.这篇 ...

  4. 运动规划 (Motion Planning): MoveIt! 与 OMPL

    原创博文:转载请标明出处:http://www.cnblogs.com/zxouxuewei 最近有不少人询问有关MoveIt!与OMPL相关的话题,但是大部分问题都集中于XXX功能怎么实现,XXX错 ...

  5. java封装性之private

    public class TestDemo{ public static void main(String args[]){ Person perA= new Person(); perA.setNa ...

  6. wordpress(三)wordpress手动更新

    第一:备份数据库还有文件 第二:从WP中文官网下载最新版WordPress,下载完毕解压到你电脑上. 第三:删除博客主机上的wp-includes和wp-admin目录. 第四:将解压在本地电脑的wo ...

  7. 前端基础 JavaScript~~~ 数据处理 奇技淫巧!!!!!!

    常用的JS数据处理手段      2016-09-21          17:40:07 1.   number类型  数组中取出里面的最大/最小值: // 数组中取出 最小值 [数值] var n ...

  8. 威纶触摸屏和三菱PLC3S之间的通信设置

    触摸屏软件中: PLC型号:FX3U\FX3G 接口类型:RS-485 4W 端口:COM2(19200,E,7,1)

  9. 依赖注入 – ASP.NET MVC 4 系列

           从 ASP.NET MVC 3.0 开始就引入了一个新概念:依赖解析器(dependence resolver).极大的增强了应用程序参与依赖注入的能力,更好的在 MVC 使用的服务和创 ...

  10. 【转】excel 末尾是0 恢复数据方法

    今天从数据库里面查了点数据,用plsql导出为csv数据后用excel打开后就出问题了,显示的问题,excel中会遇到一列中因为数字太长,结果变成了用科学计数法来表示,而这种损失不可逆的,及时改变其格 ...