Функциональное программирование является усатый заниженной талией парадигм программирования.
Первоначально отнесены к летописи информатики академии, функциональное программирование была недавно возрождения, которое в значительной степени благодаря его полезности в распределенных системах (и, вероятно, также потому, что “чистые” функциональные языки, такие как Haskell трудно понять, что дает им определенное облатки) .
Жесткие функциональные языки программирования, как правило, используется, когда производительность и целостность системы являются критически — т.е. ваша программа должна делать то, что вы ожидаете в любое время и должен работать в среде, где его задачи могут быть совместно через сотни или тысячи сетевыхкомпьютеры. Clojure 1 , например, полномочия Akamai 2 , массовые содержание сеть доставки используется такими компаниями, как Facebook, в то время как Twitter лихо adopted 3 Scala 4 за большинство компонентов эффективности интенсивной и Haskell __29 | 5 используется AT& T для его сетевой безопасностиСистемы .
Эти языки имеют крутой кривой обучения для большинства интерфейсных веб-разработчиков;Однако, многие более доступным языки включают особенности функционального программирования, особенно на Python, как в своей основной библиотеки, с функциями, как map
41 ~ и | (который мы будем говорить о в немного), и с библиотеками, такими как Fn.py 6 вместе с JavaScript, еще раз, используя методы сбора, но и с библиотеками, такими как Underscore.js __43 | 7 | __8 и Bacon.js 8 .
Функциональное программирование может быть сложной, но помните, что это не только для докторов наук, ученые данных и архитектуры космонавтов.Для большинства из нас, реальная польза от принятия функциональный стиль является то, что наши программы могут быть разбиты на более мелкие, более простые части, которые являются более надежными и легче понять.Если вы переднего конца разработчик, работающий сДанные, особенно если вы форматирования данных для визуализации, используя D3, Рафаэля или тому подобное, то функциональное программирование станет важным оружием в вашем арсенале .
Поиск согласованного определения функционального программирования является жестким, и большая часть литературы опирается на несколько предчувствие заявления, как “функции как объекты первого класса» и «устранения побочных эффектов.” Только в случае, не согните мозгузлы, на более теоретическом уровне, функциональное программирование часто объясняется в терминах лямбда calculus 9 (некоторые фактически argue 10 , что функциональное программирование в основном математика), — но вы можете расслабиться.С прагматической точки зрения, начинающий должен понимать только два понятия для того, чтобы использовать его для ежедневного применения (не требуется исчисление!) .
Во-первых, данные в функциональных программ должно быть immutable, которая звучит серьезно, но просто означает, что она никогда не должна меняться.Во-первых, это может показаться странным, (в конце концов, кто нуждается в программу, которая никогда не меняется что-нибудь?), Но на практике, вы бы просто создать новые структуры данных, а не изменять те, которые уже существуют.Например, если вам нужно, чтобы манипулировать некоторые данные в массиве, то вы бы сделать новый массив с обновленными значениями, а не пересмотреть исходный массив.Легко
Во-вторых, функциональные программы должны быть stateless, которые в основном означает, что они должны выполнять все задачи, как будто в первый раз, не зная о том, что может или не может произойти раньше в исполнении программы (можно сказать, чтолицами без гражданства программа неведении о past __24 | | 11__3 ).В сочетании с неизменностью, это помогает нам думать о каждой функции, как если бы это были работать в вакууме, в блаженном неведении о чем-либо в приложении, помимо других функций.В более конкретном плане это означает, что ваши функции будут работать только на данных, передаваемых в качестве аргументов и никогда не будет полагаться на внешних ценностей выполнять свои расчеты .
Неизменность и лиц без гражданства являются ключевыми для функционального программирования и важны для понимания, но не волнуйтесь, если они не совсем смысл еще.Вы будете знакомы с этими принципами, к концу статьи, и я обещаю, что красота, точность и мощность функционального программирования будет превратить ваши приложения в ярких, блестящих, радуг данных жевать.В настоящее время, начать с простых функций, которые возвращают данные (или других функций), а затем объединить эти основные строительные блоки для выполнения более сложных задач .
Например,давайте говорить, что мы имеем ответ API:
var data = [
{
name: "Jamestown",
population: 2047,
temperatures: [-34, 67, 101, 87]
},
{
name: "Awesome Town",
population: 3568,
temperatures: [-3, 4, 9, 12]
}
{
name: "Funky Town",
population: 1000000,
temperatures: [75, 75, 75, 75, 75]
}
];
Если мы хотим использовать диаграммы или графический библиотеку, чтобы сравнить среднюю температуру в численности населения, мы должны были бы написать некоторый наличие, что делает некоторые изменения в данных, прежде чем он правильно отформатирован для нашего визуализации.Наша библиотека графиков хочет массив координаты х и у, например, так:
[
[x, y],
[x, y]
…etc
]
Здесь x
средняя температура, а y
это размер популяции .
Без функционального программирования (или без использования, что называется “императив” стиль), наша программа может выглядеть следующим образом:
var coords = [],
totalTemperature = 0,
averageTemperature = 0;
for (var i=0; i < data.length; i++) {
totalTemperature = 0;
for (var j=0; j < data[i].temperatures.length; j++) {
totalTemperature += data[i].temperatures[j];
}
averageTemperature = totalTemperature / data[i].temperatures.length;
coords.push([averageTemperature, data[i].population]);
}
Даже в надуманный пример, это уже становится трудно следовать.Давайте посмотрим, если мы можем сделать лучше .
При программировании в функциональном стиле, вы всегда ищете простых повторяемых действий, которые могут быть абстрагированы в функции.Мы можем построить более сложные функции, вызывая эти функции в последовательности (также известные как “составляющих” функций) — подробнее об этом в секунду.В то же время, давайте смотреть на шаги мы берем в процессе трансформации первоначальный ответ API для структуры, необходимой нашей библиотеке визуализации.На базовом уровне, мы выполним следующие действия на нашем данных:
- Добавить каждый номер в списке,
- Расчета в среднем,
- Получить одно свойство из списка объектов .
Мы напишем функцию для каждого из этих трех основных действий, то сочинить нашу программу от этих функций.Функциональное программирование может быть немного запутанным на первый, и вы, вероятно, соблазн проскочить в старых императивных привычек.Чтобы избежать этого, вот несколько простых правил, чтобы земля убедиться, что вы будете следовать рекомендации:
- Все ваши функции должны принять по крайней мере один аргумент .
- Все ваши функции должны возвращать данные или другая функция .
- Нет петли
ОК, давайте добавим каждое число в списке.Вспоминая правила, давайте убедитесь, что наша функция принимает аргумент (массив чисел, чтобы добавить) и возвращает некоторые данные .
function totalForArray(arr) {
// add everything
return total;
}
Пока все хорошо.Но как мы собираемся открыть каждый пункт в списке, если мы не петлю над ним?Привет вашей новой знакомой, рекурсии!Это немного сложнее, но в основном, когда вы используете рекурсию, вы создаете функцию, которая называет себя, если конкретное условие не было выполнено — в этом случае, значение возвращается.Просто глядя на пример, вероятно, самый простой:
// Notice we're accepting two values, the list and the current total
function totalForArray(currentTotal, arr) {
currentTotal += arr[0];
// Note to experienced JavaScript programmers, I'm not using Array.shift on
// purpose because we're treating arrays as if they are immutable.
var remainingList = arr.slice(1);
// This function calls itself with the remainder of the list, and the
// current value of the currentTotal variable
if(remainingList.length > 0) {
return totalForArray(currentTotal, remainingList);
}
// Unless of course the list is empty, in which case we can just return
// the currentTotal value.
else {
return currentTotal;
}
}
Слово предостережения: Рекурсия сделает ваши программы более читаемым, и это важно в программировании в функциональном стиле.Тем не менее, в некоторых языках (в том числе JavaScript), вы столкнетесь с проблемами, когда ваша программа делает большое количество рекурсивных вызовов в одной операции (в момент написания, “большой” о 10000 звонков в Chrome, 50000в Firefox и 11000 в Node.js 12 ).Подробности выходят за рамки данной статьи, но суть, что, по крайней мере, до ECMAScript 6 не released 13 , JavaScript не поддерживает то, что называется “ хвост recursion 14 “, который является более эффективным формы рекурсии.Это сложная тема, и не придет очень часто, но это стоит знать .
При том, что пути, помните, что нам нужно рассчитать общую температуру из массива температур для того, чтобы затем рассчитать среднее значение.Теперь, вместо того, чтобы цикл по каждому пункту в temperatures
массив, мы можем просто написать следующее:
var totalTemp = totalForArray(0, temperatures);
Если вы пурист, вы могли бы сказать, что наша totalForArray
функция может быть разбита еще дальше.Например, задача сложения двух чисел вместе, вероятно, прийти в других частях вашего приложения, а затем должны быть действительно его собственную функцию .
function addNumbers(a, b) {
return a + b;
}
Теперь наша totalForArray
функция выглядит следующим образом:
function totalForArray(currentTotal, arr) {
currentTotal = addNumbers(currentTotal, arr[0]);
var remainingArr = arr.slice(1);
if(remainingArr.length > 0) {
return totalForArray(currentTotal, remainingArr);
}
else {
return currentTotal;
}
}
Отлично!Возвращаясь одно значение из массива является довольно распространенным в функциональном программировании, так что он имеет особое имя, “сокращение”, который вы будете чаще слышать в качестве глагола, как и когда вы “уменьшить массив к единственному значению. “JavaScript имеет специальный метод только для выполнения этой общей задачи.Mozilla Сеть разработчиков обеспечивает полный explanation __25 | 15 , но для наших целей это так просто, как это:
// The reduce method takes a function as its first argument, and that function
// accepts both the current item in the list and the current total result from
// whatever calculation you're performing.
var totalTemp = temperatures.reduce(function(previousValue, currentValue){
// After this calculation is returned, the next currentValue will be
// previousValue + currentValue, and the next previousValue will be the
// next item in the array.
return previousValue + currentValue;
});
Но, эй, так как мы уже определили addNumber
функцию, мы можем просто использовать, что вместо .
var totalTemp = temperatures.reduce(addNumbers);
На самом деле, потому что на общую сумму до массив так здорово, давайте положить, что в его собственной функции, так что мы можем использовать его снова без того, чтобы помнить все, что запутанной вещи о сокращении и рекурсии .
function totalForArray(arr) {
return arr.reduce(addNumbers);
}
var totalTemp = totalForArray(temperatures);
Ах, теперь that некоторые читаемый код!Только так вы знаете такие способы, как reduce
распространены в самых функциональных языков программирования.Эти вспомогательные методы, которые выполняют действия над массивами вместо зацикливания часто называют “ функции высшего порядка .”
Грузоперевозки прямо вдоль, вторая задача мы перечислили был вычисления среднего.Это довольно легко .
function average(total, count) {
return total / count;
}
Как мы могли бы идти о получении среднего для всего массива
function averageForArray(arr) {
return average(totalForArray(arr), arr.length);
}
var averageTemp = averageForArray(temperatures);
Надеюсь, вы начинаете видеть, как объединить функции для выполнения более сложных задач.Это возможно потому, что мы следуем правилам, установленным в начале этой статьи, а именно — что наши функции всегда должны принимать аргументы и возвращают данные.Довольно удивительным .
Наконец, мы хотелиполучить одно свойство из массива объектов.Вместо того чтобы показывать вам больше примеров рекурсии, я в погоню и ключ вам на другой встроенный метод JavaScript: map 16 .Этот метод, когда у вас есть массив с одной структуры и должны сопоставить его с другой структурой, например, так:
// The map method takes a single argument, the current item in the list. Check
// out the link above for more complete examples.
var allTemperatures = data.map(function(item) {
return item.temperatures;
});
Это довольно круто, но тянет одно свойство из коллекции объектов является то, что вы будете делать все время, так что давайте сделаем функцию только для этой .
// Pass in the name of the ...
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров