Erlang能否震撼Ruby界

           Erlang
            是由爱立信公司开发的一种平台式语言,可以说是一种自带了操作系统平台的编程语言,而且在这个平台上实现了并发机制、进程调度、内存管理、分布式计算、网络通讯­等功能,这些功能都是完全独立于用户的操作系统的,它采用的是类似于Java一样的虚拟机的方式来实现对操作系统的独立性的。


            介绍一下Erlang先:


            1、并发性:Erlang的轻量级进程可以支持极高的并发性,而且在高并发的情况下内存使用相当的少。Erlang的并发性并不会受到宿主操作系统并发性的限制­。

 

            2、分布式:最开始Erlang的设计目标就是实现分布式环境,一个Erlang的虚拟机就是一个Erlang网络上的节点。一个Erlang节点可以在另一个­Erlang节点上创建自己的并发进程,而子进程所在的节点可能是运行其他的操作系统的服务器。不同节点的之间的可以进行极为高效而又精确的通信,就像它们运行­在同一个节点一样。

 

            3、鲁棒形:Erlang内部建设有多种错误检测原语。我们可以通过这些原语来架设高容错性的系统。例如,一个进程可以监视其他进程的状态和活动,即使那些被监­控的进程处于其他节点。在分布式状态下,我们可以把系统配置成具有Fail-over功能的分布式系统。当有其他节点出错的时候,系统会把他的运行场景自动快速­的切换备份节点上。Erlang支持9个9的级别的故障率,一年只有几分钟的故障时间。

 

            4、软实时:Erlang是一个“软”实时系统(Soft Real
            Time),它可以提供毫秒级别的响应。


            一般的情况下,使用Erlang系统可以比其他系统的并发能力(例如Web会话负载)放大20~30倍。

 

           erlang当初是为电信系统设计的,电信系统的要求,按照Dacker给出的说法是10个:

            * 系统必须处理极大数目的并发活动;
            * 动作必须及时在某一个点得到处理,或在一定的时间内得到处理;
            * 系统可能分布在数台计算机上
            * 系统用于控制硬件
            * 软件系统非常庞大
            * 系统具备复杂的功能
            * 系统应该在很多年间持续运行
            * 在不停止系统的前提下进行软件维护(例如重新配置)
            * 严格的质量和可靠性需求
            * 必须同时对硬件失败和软件错误容错

            Joe Armstrong继续针对这些要求分析:
            * 并发性--几万人可能同时和交换机交互,因此交换系统具有内在的并发性要求。系统必须能够同时处理数万的并发活动
            * 软实时--电信系统中很多操作必须在一个给定的时间段内执行。
            o 某些限时的操作是被严格强制的,如果不能再规定的时间间隔内完成,则整个操作将被终止。
            o 其他的操作可能只被计时器监视,如果时间到没有完成(计时器事件触发),那么操作将被重复执行
            o 编写这样的系统需要非常高效地维护数万个计时器
            * 分布式--交换系统内在就是分布式的,系统的结构必须很容易从单节点扩展到多节点的分布式系统
            * 硬件交互--交换系统必须控制和监视大量的外设硬件。必须能够编写高效的设备驱动程序,在不同硬件驱动程序之间的上下文切换应该非常高效
            * 庞大的软件系统 -- 例如AXE10和AT&T 5ESS有几百万行代码。我们的系统必须能够运行于几百万行的源代码
            *
            功能复杂性--交换系统功能非常复杂。市场压力鼓励系统的开发和部署需要大量的复杂功能。通常,在没有非常好的理解这些功能之间的交互行为之前,系统就被部署了。在系统的生命周期中,可能需要用很多方式更改和扩展系统的功能。但是这些更改不能停止系统。

            * 持续运作--电信系统必须在很多年内持续运作。软件和硬件维护必须不能停止系统
            * 质量需求--交换系统必须在一定的接受层次上容忍错误的发生。电话交换必须极端可靠
            *
            容错--交换系统应该是“容错的“。意味着我们知道错误会发生,必须设计一种软硬件基础结构,能够处理这些失败,提供一个可接受层次的服务,即使发生错误。

 

            erlang针对这些方面提出的解决方案包括:
            总体原则是任何软件(硬件)系统都是会包含错误的,你认识到错误是必然发生的来编写代码。看起来是矛盾的,但却更容易编写出更加强壮的代码。采用的方式是fail-fast(这个我以后解释)

            1。采用轻量无共享的process,按照Ulf Winger的说法 Also, the number of processes can
            be way larger than 50,000. We consider 30-50,000 processes to be
            afairly normal number.有一套完备的process调度机制,最新版本已经支持SMP。
            2。无共享有很多意义,包括能够得到极高的并行度和效率提升(Amdahl's
            Law).另一方面,无共享也意味着一个process失败不会导致其他process的死锁和失败,实现失败隔离
            3。erlang有一套完备的库,其中提供了各种各样的抽象behaviour,特别是supervisor
            tree,能够管理其他进程的活动,包括监控、重新启动的策略等等、这是一个树
            4。erlang是一种functional 语言,其中很多的行为有利于编写更加可靠的代码,例如single
            assignment,就是一次赋植,不再变化,这样在发生错误的时候,你就可以从原先的状态开始,重新启动任务。从可靠性的角度来说,这相当于内存事务。这方面很多组织和大学,包括微软也有研究

            5。进程间没有任何共享,所有的通讯都是消息传递,而即使在同一台机器上,erlang也是假设这些消息传递是不可靠的,因此不管是在单台机器还是分布式处理上,你的编程方法和思路没有任何变化,因此非常适合进行分布式运算,并且非常容易伸缩

            6。函数性语言以其精确和抽象闻名于世,可以编写复杂且易于维护的项目
            7。独立的代码服务进程,可以同时允许统一份代码的不同版本在某一时刻同时运行,最后不停止系统切换到新的版本,也是通过消息处理机制进行处理
            8。一套完整的机制进行程序打包、组织,模块更新,应用更新等等
            9。erlang的虚拟机是比较高效的,除了函数性语言本身的一些特点(例如GC的很多方面可以更加高效、简洁)外,还支持直接编译到native
            code(HiPE)等等

 

            本文很长。前面是parallel/concurrent FP lanugages介绍。
            中间是自己选择ErLang和评估parallel/concurrent FP lanugages的原因。
            最后是ErLang, Yaws, Mnesia的一些讲解。

            这里有一个link,是一个很好的各种FP language的概述。

            http://www.cs.nott.ac.uk/~gmh/faq.html

            其中有一个分类是concurrent。其中包括ErLang。
            concurrent分为 strict 和 non strict (lazy)两种。ErLang is strict。
            non strict (lazy) concurrent FP Language包括:
            Clean
            Id
            这两个语言还有点评估的价值。可是很遗憾,这两个语言的名字太混同一般了,基本无法搜索。还有一个例子是self语言。一个语言起了这样的名字,基本等于宣判了自己的死刑。
            网站起个这样的名字还行。一门语言一定要有一个足够特殊的名字,能够排在搜索结果前列的。

            5.10. Id
            Id is a dataflow programming language, whose core is a non-strict
            functional language with implicit parallelism. It has the usual
            features of many modern functional programming languages, including
            a Hindley/Milner type inference system, algebraic types and
            definitions with clauses and pattern matching, and list
            comprehensions.

            5.3. Clean

            The Concurrent Clean system is a programming environment for the
            functional language Concurrent Clean, developed at the University of
            Nijmegen in The Netherlands. The system is one of the fastest
            implementations of functional languages available at the time of
            writing. Through the use of uniqueness typing, it is possible to
            write purely functional interactive programs, including windows,
            menus, dialogs, etc. It is also possible to develop real-life
            applications that interface with non-functional systems. With
            version 1.0, the language emerged from an intermediate language to a
            proper programming language. Features provided by the language
            include:

            * Lazy evaluation;
            * Modern input/output;
            * Annotations for parallelism;
            * Automatic strictness analysis;
            * Annotations for evaluation order;
            * Inferred polymorphic uniqueness types;
            * Records, mutable arrays, module structure;
            * Existential types, type classes, constructor classes;
            * Strong typing, based on the Milner/Mycroft scheme.

            Concurrent Clean is available for PCs (Microsoft Windows, Linux),
            Macintoshes (Motorola, PowerPC), and Sun4s (Solaris, SunOS). The
            system is available by ftp from:

            Host:   ftp.cs.kun.nl;
            Directory:   /pub/Clean.

            Further information about Concurrent Clean is available on the web
            from:

            http://www.cs.kun.nl/~clean.

            A book describing the background and implementation of Concurrent
            Clean is also available:

            * "Functional programming and parallel graph rewriting", Rinus
            Plasmeijer and Marko van Eekelen, Addison Wesley, International
            Computer Science Series. ISBN 0-201-41663-8

            Id 和 Clean 的语法很像,都有Haskell的影子,可以定义类型,可以定义Function Type。

            我觉得,Id 比 Clean的评估价值要小。就放在前面说吧。
            Id是一个Parallel语言。这是什么意思呢?我也不明白。好像就是没有 send, receive, thread,
            process这些概念。语句本身就是parallel执行的。不象ErLang,必须要用process,才是concurrent
            programming。我想这也是parallel和语言concurrnet语言的区别吧。
            Id程序可以成为静态类型进行编译检查,也可以成为动态类型运行时检查。
            Id语言和并发相关的一个关键语法是 --- 。用来隔开上下语句。

            statements 1 ..
            ---
            statements 2

            表示---上面的语句全部执行完,后面才可以执行。可见,在需要保证顺序的时候,要使用这个---。

            Clean 的语法和Id,haskell比较类似。和python的tab space
layout一样,需要用space来控制scope。
            Clean语言提到了一个重要概念是,Term Graph Rewriting Systems。这个我就不懂了。
            我也没有看到Clean的send receive process这样的语句。可能也是在语句级别进行的parallel。
            因为Clean 和 Id一样,function本身都是pure的,只是Id可以引入impure,需要用---来控制。
            我觉得,Clean比Id更值得评估。原因可能是看到的Clean的资料比较多一些。

            说完了Id 和 Clean。来看其他几个。concurrent strict FP languge.
            Erlang
            NESL
            Oz
            Pizza
            Sisal

            首先要排除两个。一个是Pizza,这是一个generic java。一个是Oz。
            Oz是一个OO Concurrent Language。Oz也有一定的评估价值。

            5.17. Oz

            Oz is a concurrent constraint programming language designed for
            applications that require complex symbolic computations,
            organization into multiple agents, and soft real-time control. It is
            based on a new computation model providing a uniform foundation for
            higher-order functional programming, constraint logic programming,
            and concurrent objects with multiple inheritance. From functional
            languages Oz inherits full compositionality, and from logic
            languages Oz inherits logic variables and constraints (including
            feature and finite domain constraints.) Search in Oz is encapsulated
            (no backtracking) and includes one, best and all solution
strategies.

            DFKI Oz is an interactive implementation of Oz featuring am Emacs
            programming interface, a concurrent browser, an object-oriented
            interface to Tcl/Tk, powerful interoperability features (sockets, C,
            C++), an incremental compiler, a garbage collector, and support for
            stand-alone applications. Performance is competitive with commercial
            Prolog and Lisp systems. DFKI Oz is available for many platforms
            running Unix/X, including Sparcs and 486 PCs, and has been used for
            applications including simulations, multi-agent systems, natural
            language processing, virtual reality, graphical user interfaces,
            scheduling, placement problems, and configuration.

            Further information about Oz is available on the web from:

            http://www.ps.uni-sb.de/oz/

            or by ftp from:

            Host:   ftp.ps.uni-sb.de;
            Directory:   /pub/oz.

            Specific questions on Oz may be emailed oz@ps.uni-sb.de. You can
            join the Oz users mailing list by emailing
            oz-users-request@ps.uni-sb.de.

            Oz/Mozart平台是类似于ErLang/OTP的一个平台。只是不知道性能比较如何。也没有搜索到数据。据说,Oz语言的本身效率和ErLang差不多,如果ErLang不使用特殊的VM优化。这个不奇怪,ErLang本身的语言效率并不高,我看了很多语言效率的比较,ErLang基本排在中下游。ErLang的优势在于并发。Oz应该也是类似的。只是Oz是OO语法。各方面的具体功能性能表现如何。我就不清楚了。没有具体看过。

            就剩下两个 NESL,Sisal。
            5.15. NESL

            NESL is a fine-grained, functional, nested data-parallel language,
            loosly based on ML. It includes a built-in parallel data-type,
            sequences, and parallel operations on sequences (the element type of
            a sequence can be any type, not just scalars). It is based on eager
            evaluation, and supports polymorphism, type inference and a limited
            use of higher-order functions. Currently, it does not have support
            for modules and its datatype definition is limited. Except for I/O
            and some system utilities it is purely functional (it does not
            support reference cells or call/cc).

            The NESL compiler is based on delayed compilation and compiles
            separate code for each type a function is used with (compiled code
            is monomorphic). The implementation therefore requires no type bits,
            and can do some important data-layout optimizations (for example,
            double-precision floats do not need to be boxed, and nested
            sequences can be laid out efficiently across multiple processors.)
            For several small benchmark applications on irregular and/or dynamic
            data (for example, graphs and sparse matrices) it generates code
            comparable in efficiency to machine-specific low-level code (for
            example, Fortran or C.)

            The current implementation of NESL runs on workstations, the
            Connection Machines CM2 and CM5, the Cray Y-MP and the MasPar MP2.

            Further information about NESL is available on the web from:

            http://www.cs.cmu.edu/afs/cs.cmu ... ublic/www/nesl.html

            or by ftp from:

            Host:   nesl.scandal.cs.cmu.edu;
            Directory:   nesl.

            You can join to the NESL mailing list by emailing
            nesl-request@cs.cmu.edu.

            5.20. Sisal

            Sisal (Streams and Iteration in a Single Assignment Language) is a
            functional language designed with several goals in mind: to support
            clear, efficient expression of scientific programs; to free
            application programmers from details irrelevant to their endeavors;
            and, to allow automatic detection and exploitation of the
            parallelism expressed in source programs.

            Sisal syntax is modern and easy to read; Sisal code looks similar to
            Pascal, Modula, or Ada, with modern constructs and long identifiers.
            The major difference between Sisal and more conventional languages
            is that it does not express explicit program control flow.

            Sisal semantics are mathematically sound. Programs consist of
            function definitions and invocations. Functions have no side
            effects, taking as inputs only explicitly passed arguments, and
            producing only explicitly returned results. There is no concept of
            state in Sisal. Identifiers are used, rather than variables, to
            denote values, rather than memory locations.

            The Sisal language currently exists for several shared memory and
            vector systems that run Berkeley Unix(tm), including the Sequent
            Balance and Symmetry, the Alliant, the Cray X/MP and Y/MP, Cray 2,
            and a few other less well-known ones. Sisal is available on
            sequential machines such as Sparc, RS/6000, and HP. Sisal also runs
            under MS-DOS and Macintosh Unix (A/UX). It's been shown to be fairly
            easy to port the entire language system to new machines.

            Further information about Sisal is available on the web from:

            http://www.llnl.gov/sisal/SisalHomePage.html.


            NESL,Sisal简单看了一下,好像都是学术性比较强的。没有看到一个类似于ErLang/OTP和Oz/Mozart那样的大型应用平台。有点和Id,
            Clean相似,可以并行计算多维array之类的。属于dataflow concurrency, nested data
            concurrency之类的。

            ------------------------------------------------------------------------------------------

            好了。前面说了那么多。现在来说,为什么要评估这些语言。下面从头说起。
            用了C++之后,我开始使用Java,马上就觉得Java比C++简单多了,好用多了。感觉就可以这么一直用下去。
            T1鼓吹SICP的时候,我也跟着学习FP之类的语言,haskell, ocaml, Scheme, 等,只是为了能够多借鉴一些设计思路。
            Ruby,
            Python热起来的时候,我也大致看了一下语法。觉得不过是动态OO而已。也没有打算换。那时候,还以为Rails是叫好不叫座。没想到Rails真的起来了,而且java将死已死的论调甚嚣尘上。这时候,才真的感受到一种危机感。
            再回头看手中的一套Java Frameworks。view, orm, mvc, 这些。除了view
            template比较成熟,很有信心做得最好之外。orm 和
            mvc都只发布了初级版本,正打算完全投入作出两个至少在很多方面达到最好的同类别的框架。但是这两个框架的工作量,尤其是orm的工作量,远远超过了view
            template。
            为了做好它们,我反复地修改设计。最后越来越倾向于整个系统,统一的窄接口(这就是FP的风格了),比如,一个参数的用,Object
            load1(object); 两个参数的用,load2(object,
            object)。这样才可以达到集中完全控制和最大的重用,而不需要引入Reflection和code generation等AOP手段。
            在这些设计中,类型已经阻挡了重用。当然,系统的非接口部分的实现部分,还是需要类型检查的。而且还有IDE提示。虽然已经体会到动态语言的好处,但是,如果不是受到java将死已死舆论的冲击,我还是打算继续使用Java的。毕竟已经熟悉了。

            我也考虑过转向一种动态语言。我考察了php, python, ruby。php很快被排除了。python的java like
            nested package我比较喜欢。只是这个tab space
            layout,不是很容易控制。ruby的特性还是比较多的。虽然没有package这样的文件管理特性,但是module用来做namespace一样挺好用。
            下面就python, ruby的web框架。python的我看了一下,觉得一般,不比rails好,也没有什么好的达到java
            framework的设计。rails的设计我一直觉得不怎么样,只是占了动态语言ruby的便宜。而且mixin这种加宽接口宽度,
            method个数的做法,我不是很赞成。所以,有点不甘心转到rails。即使要转到ruby,我也宁可自己写orm,
            mvc。不过这太费时间了。因为fastm还要移植。

            第一次注意到ErLang,yaws,还是T1的介绍。后来T1,
            Potian都开始宣扬ErLang。我才开始严肃考虑ErLang的可行性。最终让我下定决心的是mnesia。OODB。对我来说,容量应该够了。不需要自己写ORM
            / Cache了。如果转向Ruby,我想我忍受不了ActiveRecord(只是习惯问题,
            ActiveRecord是有亮点的),我可能还需要自己开发ORM,正如我忍受不了hibernate,JDO,
            iBatis一样(也是习惯问题。这些都是优秀的ORM,我参考了许多)。

            经历了这一次Java将死的恐慌。我吸取了教训。选择一门语言,产生对一门语言的信心,应该仔细的评估和比较。
            选择ErLang是一个风险操作。我想确认目前确实没有更好的选择了。于是就进行了调查和评估。当然,远远不够全面。另外,就是多了解各种语言的特性,做到心中有数,下次某个语言将死的时候,换哪个语言都不会感到有语法上的惊讶感。
            这还是手里没货,心中没底。如果我的产品已经跑起来了。我才不管别人炒作什么语言呢。也不管别人唱衰什么语言。现在的状态,革命远远没有成功。还要受到语言生命力的限制。

            -------------------------------------------------------------------------------

            下面介绍这两天调查ErLang, Yaws, Mnesia的结果。

            ErLang的语法比较简单。比Clean, Id等同样是concurrent的语言简单多了。
            FP的共有特点就是Pattern Match用的很多。这个Pattern Match很像OO里面的overload重载。
            只不过,OO的overload重载,是根据参数个数和类型的不同,来进行重载。
            FP的Pattern Match则是参数个数和类型的不同,还有参数值的不同,来进行重载。
            比如,
            f(1)->1,
            f(n) -> n * f(n - 1).
            就相当于
            f(n)->
            case n of
            1 -> 1
            n -> n * f(n - 1)

            Pattern Match还可以根据参数个数的不同。这个例子就不用写了。pattern match还可以加guard。就是条件判断。比如
            f(1)->1,
            f(n) when n > 1, n < 100 end -> n * f(n - 1).

            相当于
            f(n)->
            case n of
            1 -> 1
            n when n > 1, n < 100 end -> n * f(n - 1)

            可见,pattern match就是swtich, if else. 且慢,还没有完。
            pattern match最重要的特性是,variable bind。就是说,你的match
            part如果是常数,那么就作为判断条件,如果是一个变量名,那么就把那个位置的值,给这个变量。比如

            case (flag, value) of
            ok, tempVar -> 1 + tempVar
            error, _ -> 0.

            这里的ok是一个常数,而tempVar是一个变量。如果flag是ok,那么就走到ok, tempVar -> 这个分支。同时让
            tempVar = var。
            记住,case 或者 function定义的 pattern match有两个作用,一个是条件判断,一个是变量赋值。

            而 = 的pattern match就是单纯的变量赋值了。比如。
            {a, b} = { 10, 12 }
            相当于
            a = 10,b = 12。
            按照位置匹配。这个特性很有用处。从一个tuple里面取出某一个元素,基本上就采用这种方法。

            ErLang是否能够做到AOP。是可以的。
            一种是High Order Function。
            f = g(x)-> x + 1;
            f(1);
            这类似于dynamic method.invoke。效率稍微低一点。
            我们可以用这样的proxy wrapper手段,来实现AOP。类似于Spring的IoC container。
            f = generateProxy( g ) -> temp(x) -> log befoer, g(x), log after.
            f(x);

            还有一种reflection的方法。
            apply( module name, fucntin name, arg list);

            可以模拟类似于reflection aop interceptor的方式。

            reflectiveAOP( module name, fucntion name, arg list)->
            log module name,
            log function name,
            log arg list,
            apply( module name, fucntin name, arg list);
            log after  

            不过,要注意的是,
            apply( module name, fucntin name, arg list);
            这个方法很慢。是正常调用时间的8倍。

            剩下的没什么可说了。concurrent特性需要用到send, receive, process, node,
            port这些概念。可以自己看。很直观。

            下面来说mnesia, 这个oodb。
            ErLang standard Lib有一个ets,是一个memory
            hash。还有一个dets,是ets的disk版本。它们可以作为cache使用。
            mnesia是我知道的唯一的一个容量和性能不差于open source rdb 的 open source oodb。
            mnesia, ets, dets 的查询语句都是 Query List
            Comprehension。都是ErLang本身语法。所以可以避免ORM, Object Query, EQL, HQL之类。

            不过看了手册,感觉管理起来挺麻烦的。很多命令之类的。没有仔细看。

            下面说yaws。这个web server。
            ErLang 本身带有一个HTTP Server , 叫做 inet。
            yaws 对于 inet,就相当于 servlet 对于 http server。
            yaws 可以说是一个web开发框架了。

            下面来说,yaws的安装问题。yaws的linux安装最简单了。
            但是, windows install 我就是没有找到官方文档。
            Mac用户也别得意。我也没找到mac的。不过好像有freeBSD的,只是好像。

            我搜索了半天。
            后来发现YawsPack ( jabber ) 好像可以直接安装在 windows,提供了install 的步骤。
            3M多。解开之后,都是beam文件。
            还有一个erlang-repos,据说也可以安装在windows。100M。还没有尝试。
            我一向不喜欢鼓捣安装环境系统什么的。放在后面再说。

            下面说yaws开发框架的功能。
            yaws的ehtml类似于jsp, php, ruby template。
            yaws支持page centric (like php) 和 controller centric两种方式。
            page centric 好说,就是一个 xxx.yaws文件。url 指定就可以了。
            controller centric 需要配置一个 appmods。

            yaws基本上该支持的都只持了。url, url parameter, post parameter, file upload,
            json, haXe。
            只是这个url parameter, post parameter的获取方法还是两个不同的function。queyvar 和
            postvar。这也容易统一,自己用一个function包装一下就可以了。 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值