Функциональное программирование является усатый хипстеров парадигм программирования.
Первоначально отнесены к летописи информатики академии, функциональное программирование была недавно возрождения, которое в значительной мере обусловлено его полезности в распределенных системах (и, вероятно, еще и потому, “чистые” функциональные языки, такие как Haskell трудно понять, что дает им определенное отличительный знак) .
Строгие функциональные языки программирования, как правило, используется, когда производительность и целостность системы являются критически — т.е. ваша программа должна делать то, что вы ожидаете в любое время и должен работать в условиях, когда его задачи могут быть распределены по сотням или тысячам сетевыхкомпьютеры. Clojure 1 , например, полномочия Akamai 2 , массивная сеть доставки контента используется такими компаниями, как Facebook, в то время как Twitter лихо adopted 3 Scala 4 за большинство компонентов сокращает производительность, и Haskell 5 используется AT& T для его сетевой безопасностиСистемы .
Эти языки имеют крутой кривой обучения для большинства интерфейсных веб-разработчиков;Однако, многие более доступным языки конструктивные особенности функционального программирования, особенно Python, как в ее основной библиотеки, с функциями, как map
и reduce
(который мы будем говорить о в немного), а также с библиотеками, такими как Fn.py 6 вместе с JavaScript, снова используя методы сбора, но и с библиотеками, такими как Underscore.js 7 и Bacon.js 8 .
Функциональное программирование может быть сложной, но помните, что это не только для докторов наук, ученые архитектуру данных и космонавтов.Для большинства из нас, реальная выгода от принятия функциональный стиль является то, что наши программы могут быть разбиты на более мелкие, более простые части, которые являются более надежными и легче для понимания.Если вы переднего конца разработчик, работающий сДанные, особенно если вы форматирования данных для визуализации с помощью D3, Рафаэля или тому подобное, то функциональное программирование станет важным оружием в вашем арсенале .
Поиск последовательное определение функционального программирования является жестким, и большая часть литературы опирается на несколько предчувствие заявления, как “функции как объекты первого класса» и «устранение побочных эффектов.” На всякий случай, не сгибать ваш мозг вузлы, на более теоретическом уровне, функциональное программирование часто объясняется в терминах лямбда calculus 9 (некоторые фактически argue 10 , что функциональное программирование в основном по математике), — но вы можете расслабиться.С более прагматичной точки зрения, начинающий должен понимать только два понятия для того, чтобы использовать его для ежедневного применения (не требуется исчисление!) .
Во-первых, данные в функциональных программ должны быть immutable, которая звучит серьезно, но просто означает, что она никогда не должна меняться.Во-первых, это может показаться странным, (в конце концов, кто нуждается в программу, которая никогда не меняется что-нибудь?), Но на практике, вы бы просто создать новые структуры данных, а не изменять те, которые уже существуют.Например, если вам нужно манипулировать некоторые данные в массиве, то вы бы сделать новый массив с обновленными значениями, а не пересмотреть исходный массив.Легко
Во-вторых, функциональные программы должны быть stateless, которые в основном означает, что они должны выполнять все задачи, как будто в первый раз, не зная, что может или не может случиться в начале выполнения программы (можно сказать, чтолицами без гражданства программа неведении о past 11 ).В сочетании с неизменностью, это помогает нам думать о каждой функции, как если бы работали в вакууме, в блаженном неведении о чем другом в применении, помимо других функций.В более конкретном плане это означает, что ваши функции будут работать только на данных, передаваемых в качестве аргументов и никогда не будет полагаться на внешние ценностей выполнять свои расчеты .
Неизменность и лиц без гражданства являются ключевыми для функционального программирования и важны для понимания, но не волнуйтесь, если они не вполне имеет смысл еще.Вы будете знакомы с этими принципами, к концу статьи, и я обещаю, что красота, точность и мощь функционального программирования превратит ваши приложения в ярких, блестящих, радуг данных жевать.В настоящее время, начать с простых функций, которые возвращают данные (или других функций), а затем объединить эти основные строительные блоки для выполнения более сложных задач .
Например,давайте, у нас есть ответ 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 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 ...
Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров