与二郎共事十年的教训(2018年)

2020-07-16 06:25:38

那一年是2008年。我有一份稳定的.NET开发人员工作。然后我看到一家公司的广告,该公司正在寻找了解erlang…的开发人员。或者函数式编程,我申请了。

我在大学里学过一点Haskell,我很喜欢它,但是我离函数式编程的经验还差得很远。然而,有一种感觉告诉我,这是一条正确的道路。

我完全没有准备好,但准备好即兴发挥看看,我来到诺瓦门斯接受采访。我在那里遇到了Juanjo,但更重要的是,我遇到了Erlang!

在这些事件发生10年后,我学到了一些教训,我想与大家分享。

请注意,尽管这些课程帮助我编写了更好的代码,但它们不应被视为必须遵循的严格规则。正如我的导师赫尔南所说,这些都是试探法。它们可能会帮助您构建有史以来最好的Erlang系统,但更多的是作为参考或指南。在某些情况下,您肯定需要弯曲甚至完全折断它们(…。

作为一种语言,Erlang非常简单,只有很少的类型、几个关键字和一组非常基本的操作。这些都是庞大系统的基础,您应该完全学习和理解它们。

但您还应该学会在此基础上构建抽象。想想高阶函数、列表理解、OTP行为、SUMO_REST等库。它们都封装了共享的知识,通过去掉重复的部分,让您只专注于系统需要的特定内容,从而使您作为开发人员的生活变得更轻松。

消息传递之类的事情!而接收、列表递归、手动解析XML等在大型系统中应该很少使用。相反,您应该使用正确的库、框架或语法(例如,动态口令、列表理解、xmerl等)。如果您发现自己一遍又一遍地编写类似的东西,那么您应该考虑将这些通用部分抽象到一个库中。

使用更高级别的构造(库、框架、工具),而不是从头开始构建一切。如果还没有更高阶的构造,则构建一个。

在我在Erlang Solutions博客上撰写的这篇文章中,可以找到有关这方面的更多信息。

软件开发(正如Hernán用西班牙语描述的那样)可以看作是构建现实的可计算模型的过程,特别是在开发的早期阶段,当您设计系统时。

这些模型包括真实世界中存在的实体的表示。在OOP中,人们会为此使用对象。在其他函数式语言中,如Haskell,我们会使用类型。但是Erlang的类型非常有限,原则上不允许您定义自己的类型。

那么,该怎么办呢?您必须组合这些类型来表示您的实体(例如,使用标记的元组、记录等)。但那很快就会变得一团糟。

这就是为什么我建议使用不透明的数据结构。ODS是具有不透明导出类型和管理它们所需的所有逻辑的模块。它们公开一个函数接口供其他人使用,而不用担心类型的内部表示。

在我的这两次演讲(一次在EFLBA2017和另一次在CodeBEAM SF 2018)…中了解有关此主题的更多信息。

这并不是Erlang所特有的,TDD通常是创建软件的一种很好的方法。我不会在这里详细介绍它的优点,但我要说,Erlang使使用TDD变得非常容易。

例如,下面是我在教我的学生学习递归时给他们的一个作业的例子:

-模块my_list。-导出[测试/0]。test()->;[]=MY_LISTS:RUN_LENGTH([]),[{a,1}]=MY_LISTS:RUN_LENGTH([a]),[{a,1},{b,1}]=MY_LISTS:RUN_LENGTH([a,b]),[{a,2}]=MY_LISTS:RUN_LENGTH([a,a]),[{a,2},{b,1},{a,1}]=MY_LISTS:RUN_LENGTH([a,a])。a]),…。好的。

该模块进行编译(由于其动态特性,Erlang编译器不会责怪我没有在其中定义RUN_LENGTH/1函数),但是当您尝试运行它时…。

现在,在纯TDD方式下,系统提示我定义RUN_LENGTH/1。

看到这有多容易了吗?对于更复杂的系统,您可以使用Common Test之类的工具,它们的工作方式与上面的test/1函数完全一样,使用模式匹配来确定测试是通过还是失败。

在我看来,在Erlang中构建系统时没有理由不这样工作。

元测试,就像借用自Hernán的Inakos d̶e̶f̶i̶n̶e̶d̶一样,是编写测试来验证代码的特定属性而不是其行为的实践。换句话说,作为测试或持续集成过程的一部分,我们的想法是使用透析器、xref、elvis等工具检查您的代码。

如果一旦项目成熟,您就开始使用透析器、外部参照或猫王…。你将不得不花很多时间试图解开透析器警告的神秘含义。别忘了…

透析器永远不会错。透析器发出的警告表示某处有故障。

透析器可能不会警告你一些问题,但如果它发出警告(尽管可能令人困惑),那就意味着你在某个地方遇到了问题。也许这不是报告警告的地方,但您确实有需要修复的地方。

现在,破译透析器在数万行代码的代码库上第一次运行时发现的内容可能是具有挑战性的。但是,如果您从第一天开始就对您的代码运行透析程序,并且保持您的代码没有任何警告,那么每当您收到警告时,它只能是您刚刚更改的内容,这样更容易调试。

在您的项目中经常和一致地使用透析器、外部参照和猫王。一旦开始开发系统,就开始使用这些工具。

如果您使用普通的测试,卡塔纳测试(如上面的链接中所解释的)将使您非常容易做到这一点。您只需要添加一个如下所示的套房,就可以了。事实上,这间套房通常是我在所有项目中添加的第一间套房。

大型系统往往有更大的测试电池。按照好的实践,您通常对每个拉请求和/或在每次部署之前至少运行一次所有这些测试。

这些都很好,但是如果保持无人值守,这些大的测试电池将开始使您的日常开发周期变得更长。测试完整性的目标(即,用测试覆盖尽可能多的系统功能)应该与测试速度相平衡。而这并不是一件容易做到的事情。

行为是动态口令的核心,然而人们一次又一次地与之抗争。如果您来自OOP领域,可能有人已经告诉您,行为类似于接口。

虽然这通常是正确的,但它隐藏了大量的复杂性,有时会导致一些错误的信念,这将不必要地使您的代码复杂化。

花时间了解你使用的行为是如何运作的,以及如何定义和使用你自己的行为。

行为是伟大的,它们非常有力,但又极其简单。通过我前段时间写的这些文章,您可以了解更多关于它们的信息,并释放它们的全部潜力:Erlang Behaviors…。以及如何在他们身边举止得体。

Erlang/OTP附带了许多有用但有些隐藏的精华,它们将帮助您作为Erlang开发人员在日常生活中提供帮助,并提高您的工作效率。你应该学会如何使用它们。

从.erlang和USER_DEFAULT到DBG、外部参照和观察者。您检查过sys模块了吗?那么Erlang:SYSTEM_INFO/1或ET呢?有许多隐藏的宝石可以让你的生活变得更轻松。

了解Erlang/OTP已经提供的所有工具,以更好地工作并避免重复发明轮子。

我来自OOP世界,当我开始使用Erlang时,我首先尝试使用的是调试器。事实证明,当您处理并发和分布式编程语言时,这不是一个好主意。

不要误会我的意思,调试器工作得非常好,功能非常强大,但它主要只是帮助您调试顺序代码。使用它调试大型系统和应用程序是…。充其量也就是笨拙。

另一方面,Erlang/OTP附带了大量工具,使跟踪和检查系统变得更容易。您可以在Dimitris Zorbas的这篇文章中找到其中的几个。除了Erlang/OTP本身提供的库之外,还有一些令人惊叹的库,比如redbug和recon。

这显然是我给任何问我关于Erlang的人的最常见的建议:参与社区。

这个社区并不庞大(正如莫妮卡·科尔斯不久前指出的那样,我们知道对方的名字),但它是积极主动的,总是有帮助的。

当您开始在Erlang工作时,迷失的感觉并不少见,许多东西都是新的,而另一些东西对于以前从未使用过这种语言的人来说是独一无二的。由于Erlang的主要优势是在构建大型系统时体验到的,因此最初的步骤可能很有挑战性。社区中的每个人都知道这一点(我们都经历过这些事情),我们在这里提供帮助。

加入邮件列表。加入“二郎松弛”号吧。在IRC上找到我们。在你附近找个聚会。

最重要的教训是:您可能最终会使用Erlang构建大量高可靠的后端系统(对我来说,这些似乎非常严重),但这并不意味着您不能享受其中的乐趣!

Erlang的设计从第0天起就考虑到了容错性和并发性,它允许您减少对这些事情的担忧,而更多地关注正在构建的内容的有趣方面。这就是二郎禅。

此外,如果你只是想玩二郎语,你可以用光束奥运会来测试你的语言知识,或者向你的朋友们挑战一场蛇…的游戏。

或…。你也可以在SpawnFest上组建一支队伍,赢得一些令人惊叹的奖品!

最后,我想借此机会感谢每一位加入我、推动我、指引我走过这条道路的人。没有特定顺序的…。

科尼和塔托(我的妻子和孩子),罗莎(我的妈妈,VB6程序员🤯),安德烈(我的兄弟)和我的其他家人。

Monika,Michal,Robert,Francesco,Csaba,Magdalena,Cldio,Nicolas,以及我在这里忘记提到的来自Erlang Solutions的那些人。

马里亚诺,曼纽尔,弗雷德,健二,乔,马克,何塞,其他乔😎,弗兰克,以及来自世界各地的埃尔朗社区的所有其他朋友。

这个博客的所有追随者和所有在我写东西的地方阅读我写的东西的人-你们太棒了,伙计们!:)。

你想为二郎沙场做贡献吗?我们在接受作家!注册一个中等帐户并与我联系(Brujo Benavides)或加入稻中社区。