学习Erlang与学习Node.js [关闭]


41

我在线上看到很多关于Erlang如何在几乎所有可能的类别中踢出node.js屁股的废话。所以我想学习Erlang并试一试,但这就是问题所在。我发现拿起Erlang比拿起node.js困难得多。使用node.js,我可以选择一个相对复杂的项目,并且一天之内就能完成工作。使用Erlang,我遇到了障碍,并且发展得不那么快。

因此,对于那些有更多经验的人来说,Erlang学习起来是否很复杂,或者我只是想念一些东西?Node.js可能不是完美的,但是我似乎能够用它完成工作。


9
也许我缺少了一些东西,但是node.js不是JavaScript库,而Erlang不是完全不同的语言吗?他们甚至有什么可比性?
FrustratedWithFormsDesigner

3
@ FrustratedWithFormsDesigner,node.js是使用多线程方法在服务器端获取javascript的最新方式/炒作的一部分,因此它们具有可比性
lurscher 2011年

5
@lurscher:您无法将Erlang(语言)与Node.js(服务器端JavaScript)进行比较。这就像将Java(语言)与Django(服务器python)进行比较。更不用说Erlang和JS也有很大的不同。
乔什·K

10
作为同时使用erlang和node的人,它们在解决的问题上绝对具有可比性
Dale Harvey

3
@Noli node.js和erlang之间有区别。您的意思是比较node.js和基于erlang的Web服务器。Erlang 在Web服务器之外有许多用户。
雷诺斯2011年

Answers:


46

首先,我同意我对学习Erlang的正确回答。它是一种主要是功能性的语言(尽管并发起着很大的作用),并且添加了它的所有功能以实现容错和鲁棒性,这与Javascript最初的设计目标并不完全相同。

其次,让Node.js进入Erlang有点错了。Node.js是单个服务器/框架,它借助回调以事件驱动的方式完成所有工作。Erlang有自己的框架(OTP),但根本不在同一个级别上。

如果您打算学习Erlang,建议您先阅读我的博客文章《致Erlang初学者的公开信》(或Onlooker)作为入门阅读,然后再学习教程。


就模式和用法而言,您唯一可以比较Erlang和Node.js的地方就是它们是事件驱动的。但是,这里有两个主要区别。Node.js的模型基于绑定到事件的回调。Erlang基于消息队列和选择性接收。里面有什么含义?

首先,如果您以基于回调的方式进行操作,则携带状态的唯一方法是使状态全局化或进入连续传递样式编程。其次,您必须自己照顾完整的事件矩阵。这样的一个例子是,如果我们想象一个非常简单的有限状态机:一个互斥信号量,是事件驱动的。

互斥量信号量具有两种状态:锁定和空闲。每当给定的计算单位(工作人员,流程,函数或线程)想要访问互斥锁时,它就必须触发一个事件,告诉它“我很感兴趣”。现在,您必须注意以下类型的事件:

  • 互斥锁是免费的,您要求获得锁
  • 互斥锁已被其他人锁定,您想获取该锁
  • 互斥锁已被您自己锁定,您想释放互斥锁

然后,您需要考虑其他事件,例如超时以避免死锁:

  • 互斥锁已被锁定,您等待了太长时间,一个定时器放弃了点火
  • 互斥锁已被锁定,您等待了太长时间,获得了锁定,然后触发了超时

然后,您还有超出范围的事件:

  • 您只是锁定了互斥锁,而有些工作人员则希望它是免费的。现在,该工作人员的查询必须排队,以便在空闲时将其处理回去。
  • 您需要使所有工作异步

事件矩阵变得非常复杂。我们的FSM在这里只有2个状态。对于Erlang(或任何具有选择性接收和异步与潜在同步事件的语言),您必须考虑以下几种情况:

  • 互斥锁是免费的,您要求获得锁
  • 互斥锁已被其他人锁定,您想获取该锁
  • 互斥锁已被您自己锁定,您想释放互斥锁

就是这样。计时器的处理与接收完成的情况相同,对于与“等待直到空闲”有关的任何事情,消息将自动排队:工作人员仅需等待回复。在这些情况下,模型要简单得多。

这意味着在通常情况下,CPS和基于回调的模型(例如,node.js中的模型)要么要求您非常聪明地处理事件,要么请您完全处理整个复杂的事件矩阵,因为对于因奇怪的时序问题和状态更改而导致的每一个无关紧要的情况,您都必须回电。

选择性接收通常使您仅关注所有潜在事件的子组,并在这种情况下让您更轻松地进行事件推理。请注意,Erlang的行为(设计模式/框架实现)称为gen_event。gen_event实现使您可以拥有一种与node.js中使用的机制非常相似的机制(如果需要的话)。


还有其他几点可以区分它们。Erlang具有抢先式调度功能,而node.js使其具有协作性,Erlang更适合某些大型应用程序(分布式和所有),但是Node.js及其社区通常更适合Web且对最新Web趋势了解。选择最佳工具是一个问题,这取决于您的背景,问题类型和偏好。就我而言,Erlang的模型非常适合我的思维方式。不一定每个人都是这样。

希望这可以帮助。


有关反应式编程以及如何在JS中进行操作的更多信息:blog.flowdock.com/2013/01/22/…–
Bart

“因为在怪异的时序问题和状态变化导致的每一个无关紧要的情况下,都必须给您回电。” -在Erlang中,您仍然需要处理计时器,并且“在完成接收的相同情况下”执行计时器这一事实并不会改变复杂性(根本)。在我看来(作为每天处理数十亿个请求的系统的架构师),选择性接收和node.js样式之间的唯一现实区别是(a)问题:“我们默认情况下想做什么”(使用node.js)默认情况下会处理事件,除非发生匹配,否则Erlang会推迟事件)...
No-Bugs Hare

...和(b)的可读性,包括样板的量(这是非常糟糕的古典node.js中,却成了很多更好- IMNSHO比二郎神的更好-与新引进的await运营商)......在任何情况下,这些差异几乎是美观的(尽管双方都有狂热分子鼓吹,否则)。
无臭兔野兔

38

Erlang的学习并不复杂,这与钱伯斯·康斯坦斯(99.44%)的编码人员在编程工作中所学的思维方式无关。您面临的问题可能只是概念上的迷失方向,而不是实际的复杂性。

以下是Erlang的一些外来功能,它们会咬住一个典型的程序员:

  • Erlang是一种(大多数)功能性的编程语言。最常见的编程语言几乎在军事上势在必行。
  • Erlang的并发模型是Actor模型。大多数常见的编程语言都使用基于锁的线程或某种形式的基于“反应堆”的并发方法。(我认为Node.js是后者,但是请不要称呼我–客户端/服务器关系的任何一侧对JavaScript的兴趣为零。)
  • Erlang具有一种“让它崩溃”的编码方法,具有强大的运行时功能,可用来捕获这些崩溃,对其进行诊断并在系统运行时对其进行热补丁。大多数常见的编程语言都认可一种高度防御性的编程风格。
  • Erlang几乎(但不是完全)与庞大而温和的,令人费解的常用体系结构库配对,用于可靠和稳定的服务器(OTP)。(有一个原因,通常将Erlang称为Erlang / OTP。)此外,此库是基于前面提到的外来功能构建的,因此对新手来说是不透明的。大多数编程语言都具有较少使用的无所不包的库(尽管有Java EE),并且说这些库自然是基于大多数程序员更熟悉的概念构建的。

因此,与学习Node.js相比,学习Erlang对大多数程序员而言将是更大的挑战-特别是如果程序员已经熟悉JavaScript。最后,然而,一旦你过去的概念障碍,我认为Erlang的编码将是较少比相同的Node.js编码复杂。这有几个原因:

  • Erlang的并发模型使逻辑流程比典型的“反应器”风格的并发更加清晰,并且使并发比典型的基于锁的并发更加稳定和正确。对于Erlang程序员来说,在一个典型程序中实际上删除数千个进程,而在其中放入数千个线程,这几乎是没有问题的,例如Java将是一场噩梦(更不用说所涉及的内存和CPU开销)了,等同于在基于“反应器”的设置中维护数千个独立状态将是一场噩梦。
  • 作为一种(主要)功能的语言,Erlang非常类似于“所见即所得”的设置。变量一旦设置,就不会更改。曾经 没有OOP会让您感到困惑的“遥距怪异的动作”:任何与您一起工作的事物都明确地摆在您面前。没有X的继承变量,Y的类变量,Z的全局变量也不用担心。(后一点并不是100%正确,但是在如此大量的情况下正确,对于您的学习阶段就足够了。)
  • Erlang具有处理错误的强大功能,这意味着您可以使用防御性较低的编程来使代码混乱,从而使逻辑更清晰,并使代码更小。
  • 一旦使用了OTP库,它就是一个功能强大的通用代码堆栈,可让您的整个应用程序保持正常运行,并涵盖了许多使用寿命很长的服务器的问题和用例,您可能要等到为时已晚才想到。OTP库本身就是IM(ns)HO,是学习Erlang的足够充分的理由。

如果可以的话,请继续在Erlang上告白,如果尚未这样做,请访问“ 学习一些Erlang的好处”,以获取有关Erlang概念的温和且(非常)有趣的介绍。


感谢您对这篇文章。我正在阅读《学习您一些Erlang》,而我已经读了一半,但是我感觉到我需要先了解所有这些知识,然后才能真正开始适当地做点什么重要的,而不是
Noli

1
实际上,一旦您进入本书的并发部分,您就可以开始轻松地完成重要的事情。
我正确的意见

“ Erlang的并发模型使逻辑流程比典型的“反应堆”风格的并发更加清晰”-我认为尽管数十年来反应堆异步处理的确是一团糟,但随着期货(尤其是等待操作员)的到来,事实并非如此。案件了。使用await,您可以让超轻量的协程“好像”充当线程(而且我不确定JS,但是在C ++中,co_await的体系结构设计成不仅可以扩展到数千个,而且可以扩展到数十亿个)协程)。
野兔野兔

“这与钱伯斯常数(99.44%)的思维方式是异样的”-对于任何行业项目,这都被视为“大胖子”。即使不存在功能语言不受欢迎的客观原因(我不赞成,但这是一个截然不同且漫长的故事),这个大问题仍然存在。
无臭兔野兔

10

Erlang和Node之间有一些重大区别

首先是该节点是Javascript,这意味着它是一种非常通用的语言,与越来越多的人所熟悉的语言具有很多共同点,因此通常更容易启动和运行。对于大多数人来说,Erlang的语法常常很陌生和陌生,尽管语言远比javascript简单得多,但由于其独特性,它需要更多的时间来习惯

其次,Erlang有一个非常特殊的无共享并发模型,它要求您以不同的方式解决问题,这是一件好事(TM)

最后一个重要的问题是,Erlang是由一家商业公司开发的,并且是在两年后才开源的,因此人们实际上可以在源代码管理中看到单个提交,即使现在我也不认为所有的erlang开发人员都已经搬走了向公众github仓库进行开发。node.js从一开始就在社区内部构建,这意味着它对社区的支持要好得多,已经有更多的节点库,更多的社区文档,更多的实时示例,无处不在的软件包管理器等。Erlang正在追赶在这方面,它的起步幅度仍然更大。

Node将使您能够快速且相对轻松地编写有趣的事情,对于erlang已经解决了很长时间的大型应用程序,Node仍存在越来越大的麻烦。Erlang将改变您的编程方式,并且(imo)使您成为更好的程序员,但是一开始它不会使您的生活变得轻松。两者都以不同的方式很有趣。


2
值得一提的是,Node的线程也“没有共享”。
塔林2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.