相关链接:
https://medium.com/@cscalfani/so-you-want-to-be-a-functional-programmer-part-6-db502830403
Taking that first step to understanding Functional Programming concepts is the most important and sometimes the most difficult step. But it doesn’t have to be. Not with the right perspective.
怎么办?
Now that you’ve learned all this great new stuff, you’re probably thinking, “Now what? How can I use this in my everyday programming?”
- 既然你已经学会了所有这些伟大的新东西,你可能会想,“现在怎么样? 我如何在日常编程中使用它?“
It depends. If you can program in a Pure Functional Language like Elm or Haskell, then you can leverage all of these ideas. And these languages make it easy to do so.
- 这取决于。 如果您可以使用像Elm或Haskell这样的纯函数语言进行编程,那么您可以利用所有这些想法。 而这些语言使这样做变得容易。
If you can only program in an Imperative Language like Javascript, as many of us must, then you can still use a lot of what you’ve learned but there will be a great deal more discipline required.
- 如果你只能像Javascript这样的命令式语言编程,就像我们许多人一样,那么你仍然可以使用你学到的很多内容,但是需要更多的学科。
Functional Javascript
Javascript has many features that let you program in a more functional manner. It’s not pure but you can get some immutability in the language and even more with libraries.
- Javascript具有许多功能,可让您以更实用的方式进行编程。 它不是纯粹的,但你可以在语言中获得一些不变性,甚至更多的是库。
It’s not ideal, but if you have to use it, then why not gain some of the benefits of a Functional Language?
- 这不是理想的,但如果你必须使用它,那么为什么不能获得功能语言的一些好处呢?
Immutability
不变性
The first thing to consider is immutability. In ES2015, or ES6 as it was called, there is a new keyword called const. This means that once a variable is set, it cannot be reset:
- 首先要考虑的是不变性。 在ES2015或ES6中,有一个名为const的新关键字。 这意味着一旦设置了变量,就无法重置:
const a = 1;
a = 2; // this will throw a TypeError in Chrome, Firefox or Node
// but not in Safari (circa 10/2016)
Here a is defined to be a constant and therefore cannot be changed once set. This is why a = 2 throws an exception (except for Safari).
- 这里a被定义为常数,因此一旦设置就不能改变。 这就是a = 2抛出异常(Safari除外)的原因。
The problem with const in Javascript is that it doesn’t go far enough. The following example illustrates its limits:
- Javascript中const的问题在于它还远远不够。 以下示例说明了其限制:
const a = {
x: 1,
y: 2
};
a.x = 2; // NO EXCEPTION!
a = {}; // this will throw a TypeError
Notice how a.x = 2 does NOT throw an exception. The only thing that’s immutable with the const keyword is the variable a. Anything that a points to can be mutated.
- 注意a.x = 2如何不抛出异常。 const关键字唯一不可变的是变量a。 任何指向可以变异的东西。
This is terribly disappointing because it would have made Javascript so much better.
- 这非常令人失望,因为它会使Javascript变得更好。
So how do we get immutability in Javascript?
- 那么我们如何在Javascript中获得不变性呢?
Unfortunately, we can only do so via a library called Immutable.js. This may give us better immutability but sadly, it does so in a way that makes our code look more like Java than Javascript.
- 不幸的是,我们只能通过一个名为Immutable.js的库来实现。 这可能会给我们提供更好的不变性,但遗憾的是,它确实使我们的代码看起来更像Java而不是Javascript。
Currying and Composition
- 卷曲和组成
Earlier in this series, we learned how to write functions that are curried. Here’s a more complex example:
- 在本系列的前面部分,我们学习了如何编写curry函数。 这是一个更复杂的例子:
const f = a => b => c => d => a + b + c + d
Notice that we had to write the currying part by hand.
- 请注意,我们必须手工编写currying部分。
And to call f, we have to write:
- 要拨打f,我们必须写:
console.log(f(1)(2)(3)(4)); // prints 10
But that’s enough parentheses to make a Lisp programmer cry.
- 但这足以让Lisp程序员哭泣。
There are many libraries which make this process easier. My favorite one is Ramda.
- 有许多库使这个过程更容易。 我最喜欢的是Ramda。
Using Ramda we can now write:
- 使用Ramda我们现在可以写:
const f = R.curry((a, b, c, d) => a + b + c + d);
console.log(f(1, 2, 3, 4)); // prints 10
console.log(f(1, 2)(3, 4)); // also prints 10
console.log(f(1)(2)(3, 4)); // also prints 10
The function definition isn’t much better but we’ve eliminated the need for all those parenthesis. Notice that we can apply as many or as few parameters as we want each time we invoke f.
- 函数定义并没有好多少,但我们已经消除了对所有这些括号的需求。 请注意,每次调用f时,我们都可以应用尽可能多的参数。
By using Ramda, we can rewrite the mult5AfterAdd10 function from Part 3and Part 4:
- 通过使用Ramda,我们可以重写第3部分和第4部分中的mult5AfterAdd10函数:
const add = R.curry((x, y) => x + y);
const mult5 = value => value * 5;
const mult5AfterAdd10 = R.compose(mult5, add(10));
It turns out that Ramda has a lot of helper functions for doing these sorts of things, e.g. R.add and R.multiply, which means we can write less code:
- 事实证明,Ramda有许多辅助功能来做这些事情,例如: R.add和R.multiply,这意味着我们可以编写更少的代码:
const mult5AfterAdd10 = R.compose(R.multiply(5), R.add(10));
Map, Filter and Reduce
- 映射,过滤和减少
Ramda also has its own versions of map, filter and reduce. Although these functions exist in Array.prototype in vanilla Javascript, Ramda’s versions are curried:
- Ramda还有自己的map,filter和reduce版本。 尽管这些函数存在于vanilla Javascript中的Array.prototype中,但Ramda的版本仍然存在:
const isOdd = R.flip(R.modulo)(2);
const onlyOdd = R.filter(isOdd);
const isEven = R.complement(isOdd);
const onlyEven = R.filter(isEven);
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(onlyEven(numbers)); // prints [2, 4, 6, 8]
console.log(onlyOdd(numbers)); // prints [1, 3, 5, 7]
R.modulo takes 2 parameters. The first is the dividend (what’s being divided) and the second is the divisor (what we’re dividing by).
- R.modulo有2个参数。 第一个是红利(被分割的是什么),第二个是除数(我们除以的是什么)。
The isOdd function is just the remainder of dividing by 2. A remainder of 0 is falsy, not odd, and a remainder of 1 is truthy, odd. We flipped the first and second parameters of modulo so that we could specify 2 as the divisor.
- isOdd函数只是除以2的余数.0的余数是假的,而不是奇数,1的余数是真的,奇数。 我们翻转了模数的第一个和第二个参数,以便我们可以指定2作为除数。
The isEven function is just the complement of isOdd.
- isEven函数只是isOdd的补充。
The onlyOdd function is the filter function with the predicate (a function that returns a boolean) of isOdd. It’s waiting for the list of numbers, its final parameter, before it executes.
- onlyOdd函数是带有谓词(一个返回布尔函数的函数)为isOdd的过滤函数。 在执行之前,它正在等待数字列表,它的最终参数。
The onlyEven function is a filter that uses isEven as its predicate.
- onlyEven函数是一个使用isEven作为谓词的过滤器。
When we pass numbers to onlyEven and onlyOdd, isEven and isOdd get their final parameters and can finally execute returning the numbers we’d expect.
- 当我们将数字传递给onlyEven和onlyOdd时,isEven和isOdd得到它们的最终参数,并最终可以返回我们期望的数字。
Javascript Shortcomings
- Javascript缺点
With all of the libraries and language enhancements that have gotten Javascript this far, it still suffers from the fact that it’s an Imperative Language that’s trying to be all things to all people.
- 随着所有已经获得Javascript的库和语言增强功能,它仍然受到这样一个事实的影响:它是一种势在必行的语言,试图成为所有人的所有事物。
Most front end developers are stuck using Javascript in the browser because it’s been the only choice for so long. But many developers are now moving away from writing Javascript directly.
- 大多数前端开发人员都在浏览器中使用Javascript,因为它是这么久的唯一选择。 但是许多开发人员现在正在不再直接编写Javascript。
Instead, they are writing in a different language and compiling, or more accurately, transpiling to Javascript.
- 相反,他们用不同的语言编写并编译,或者更准确地说,转换为Javascript。
CoffeeScript was one of the first of these languages. And now, Typescript has been adopted by Angular 2. Babel can also be considered a transpiler for Javascript.
- CoffeeScript是其中第一种语言之一。 现在,Typescript已被Angular 2采用.Babel也可以被认为是Javascript的转换器。
More and more people are taking this approach in production.
- 越来越多的人正在采用这种方法进行生产。
But these languages started with Javascript and only made it slightly better. Why not go all the way and transpile to Javascript from a Pure Functional Language?
- 但这些语言始于Javascript,只是稍微好一点。 为什么不一直走到纯函数式语言的Javascript中?
Elm
In this series, we’ve looked at Elm to help understand Functional Programming.
- 在本系列中,我们研究了Elm以帮助理解功能编程。
But what is Elm? And how can I use it?
- 但是什么是榆树? 我该如何使用它?
Elm is a Pure Functional Language that compiles to Javascript so you can use it to create Web Applications using The Elm Architecture, aka TEA (this architecture inspired the developers of Redux).
- Elm是一种纯函数语言,可编译为Javascript,因此您可以使用它来创建Web应用程序,使用The Elm Architecture,即TEA(这种架构激发了Redux的开发人员)。
Elm programs do NOT have any Runtime Errors.
- 榆树程序没有任何运行时错误。
Elm is being used in production at companies such as NoRedInk, where Evan Czapliki the creator of Elm now works (he previously worked for Prezi).
- Elm正在NoRedInk等公司的生产中使用,Elm的创建者Evan Czapliki现在在那里工作(他以前在Prezi工作过)。
See this talk, 6 Months of Elm in Production, by Richard Feldman from NoRedInk and Elm evangelist for more information.
- 有关更多信息,请参阅NoRedInk和Elm传道者的Richard Feldman撰写的关于生产中的6个月的演讲。
Do I have to replace all of my Javascript with Elm?
- 我是否必须用Elm替换所有Javascript?
No. You can incrementally replace parts. See this blog entry, How to use Elm at Work, to learn more.
- 不可以。您可以逐步更换零件。 请参阅此博客文章“如何在工作中使用Elm”以了解更多信息。
Why learn Elm?
- 为何学习榆树?
- Programming in a Pure Functional Language is both limiting and freeing. It limits what you can do (mostly by keeping you from shooting yourself in the foot) but at the same time it frees you from bugs and bad design decisions since all Elm programs follow The Elm Architecture, a Functionally Reactive Model.
- 1.纯功能语言编程既限制又自由。 它限制了你可以做的事情(主要是通过阻止你自己在脚下射击),但同时它让你从错误和糟糕的设计决定中解脱出来,因为所有榆树程序都遵循功能反应模型Elm Architecture。
- Functional Programming will make you a better programmer. The ideas in this article are only the tip of the iceberg. You really need to see them in practice to really appreciate how your programs will shrink in size and grow in stability.
- 2.函数式编程将使您成为更好的程序员。 本文中的想法只是冰山一角。 你真的需要在实践中看到它们才能真正理解你的程序如何缩小并稳定增长。
- Javascript was initially built in 10 days and then patched for the last two decades to become a somewhat functional, somewhat object-oriented and a fully imperative programming language.
Elm was designed using what has been learned in the last 30 years of work in the Haskell community, which draws from decades of work in mathematics and computer science.
The Elm Architecture (TEA) was designed and refined over the years and is a result of Evan’s thesis in Functional Reactive Programming. Watch Controlling Time and Space to appreciate the level of thinking that went into the formulation of this design.
- Javascript最初是在10天内构建的,然后在过去的二十年中进行了修补,以成为一种功能有点,有些面向对象和完全命令式的编程语言。
Elm的设计基于Haskell社区过去30年的工作经验,该社区吸取了数十年的数学和计算机科学工作。
榆树建筑(TEA)多年来经过设计和改进,是Evan在功能反应编程方面的论文的结果。 观察控制时间和空间,以了解制定此设计的思维水平。
- Elm is designed for front-end web developers. It’s aimed at making their lives easier. Watch Let’s Be Mainstream to better understand this goal.
- Elm专为前端Web开发人员设计。 它旨在让他们的生活更轻松。 观看让我们成为主流,以更好地了解这一目标。
The Future
It’s impossible to know what the future will hold, but we can make some educated guesses. Here are some of mine:
- 我们不可能知道未来会发生什么,但我们可以做一些有根据的猜测。 这是我的一些:
There will be a clear move toward languages that compile to Javascript.
- 对于编译为Javascript的语言,将会有明确的转变。
Functional Programming ideas that have been around for over 40 years will be rediscovered to solve our current software complexity problems.
- 已经存在40多年的功能编程思想将被重新发现,以解决我们当前的软件复杂性问题。
The state of hardware, e.g. gigabytes of cheap memory and fast processors, will make functional techniques viable.
- 硬件状态,例如 数十亿字节的廉价内存和快速处理器,将使功能技术变得可行。
CPUs will not get faster but the number of cores will continue to increase.
- CPU不会变快,但核心数量将继续增加。
Mutable state will be recognized as one of the biggest problems in complex systems.
- 可变状态将被认为是复杂系统中最大的问题之一。
I wrote this series of articles because I believe that Functional Programming is the future and because I struggled over the last couple of years to learn it (I’m still learning).
- 我写了这一系列的文章,因为我相信功能编程是未来,因为我在过去几年里努力学习它(我还在学习)。
My goal is to help others learn these concepts easier and faster than I did and to help others become better programmers so that they can have more marketable careers in the future.
- 我的目标是帮助他人比我更容易,更快地学习这些概念,并帮助其他人成为更好的程序员,以便他们将来可以拥有更多适销对路的职业。
Even if my prediction that Elm will be a huge language in the future is wrong, I can say with certainty that Functional Programming and Elm will be on the trajectory to whatever the future holds.
- 即使我预测榆树将来会成为一种巨大的语言也是错误的,我可以肯定地说,功能编程和榆树将会走向未来的轨道。
I hope that after reading this series, you feel more confident in your abilities and your understanding of these concepts.
- 我希望在阅读完本系列之后,您对自己的能力和对这些概念的理解会更有信心。
I wish you luck in your future endeavors.
- 祝你未来的事业顺利。