Go функциональное программирование

Зачем вам практиковать функциональное программирование с помощью Go? Проще говоря, функциональное программирование делает ваш код более читабельным. Легче тестируемым и менее сложным из-за отсутствия состояний и изменяемых данных. Если вы столкнулись с ошибками, вы можете быстро отладить свое приложение. Если не нарушаете правила функционального программирования. Когда функции изолированы, вам не нужно иметь дело со скрытыми изменениями состояния. Которые влияют на выходные данные.

Инженер — программист и автор Эрик Эллиот определил функциональное программирование следующим образом.

Функциональное программирование-это процесс создания программного обеспечения путем составления чистых функций. Избегая общего состояния. Изменчивых данных и побочных эффектов.

Функциональное программирование скорее декларативно, чем императивно. И состояние приложения протекает через чистые функции. В отличие от объектно-ориентированного программирования. Где состояние приложения обычно совместно используется и совместно размещается с методами в объектах.

Функциональное программирование, как и объектно-ориентированное и процедурное программирование, представляет собой сдвиг парадигмы. Он навязывает уникальный способ мышления, когда дело доходит до написания кода, и вводит целый новый набор правил. Чтобы придерживаться их.

4 важные понятия для понимания

Чтобы полностью понять функциональное программирование, вы должны сначала понять следующие связанные понятия.

  1. Чистые функции и идемпотентность
  2. Побочные эффекты
  3. Функциональный состав
  4. Общее состояние и неизменяемые данные

Давайте быстро разберемся.

1. Чистые функции и идемпотенция

Чистая функция всегда возвращает один и тот же результат, если вы даете ей один и тот же вход. Это свойство также называется идемпотентностью. Идемпотентность означает, что функция всегда должна возвращать один и тот же результат. Независимо от количества вызовов.

2. Побочные эффекты

Чистая функция не может иметь никаких побочных эффектов. Другими словами, ваша функция не может взаимодействовать с внешней средой.

Например, функциональное программирование рассматривает вызов API как побочный эффект. Почему? Потому что вызов API считается внешней средой, которая не находится под вашим непосредственным контролем. API может иметь несколько несоответствий, таких как тайм-аут или сбой, или даже может возвращать неожиданное значение. Это не соответствует определению чистой функции, поскольку мы требуем последовательных результатов каждый раз. Когда вызываем API.

Другие общие побочные эффекты включают:

  • Мутация данных
  • Манипуляция DOM
  • Запрос противоречивых данных, таких как текущий DateTimeс time.Now()

3. Функциональный состав

Основная идея композиции функций проста: вы объединяете две чистые функции, чтобы создать новую функцию. Это означает, что концепция получения одного и того же выхода для одного и того же входа все еще применяется здесь. Поэтому важно создать более продвинутую функциональность, начиная с простых, чистых функций.

4. Общее состояние и неизменяемые данные

Целью функционального программирования является создание функций, которые не содержат состояния. В частности, общие состояния могут создавать побочные эффекты или проблемы изменчивости в ваших чистых функциях. Делая их нечистыми.

Однако не все государства плохи. Иногда государство необходимо для решения определенной программной задачи. Цель функционального программирования — сделать состояние видимым и явным, чтобы исключить любые побочные эффекты. Программа использует неизменяемые структуры данных для получения новых данных из использования чистых функций. Таким образом, нет необходимости в изменчивых данных, которые могут вызвать побочные эффекты.

Теперь, когда мы рассмотрели наши основы, давайте определим некоторые правила. Которым следует следовать при написании функционального кода в Go.

Правила функционального программирования

Как я уже упоминал, функциональное программирование-это парадигма. Таким образом, трудно определить точные правила для этого стиля программирования. Кроме того, не всегда возможно следовать этим правилам до T; иногда вам действительно нужно полагаться на функцию. Которая содержит состояние.

Однако, чтобы следовать парадигме функционального программирования как можно ближе. Я предлагаю придерживаться следующих рекомендаций.

  • Никаких изменяемых данных чтобы избежать побочных эффектов
  • Отсутствие состояния (или неявное состояние, например счетчик циклов)
  • Не изменяйте переменные после присвоения им значения
  • Избегайте побочных эффектов, таких как вызов API

Одним из хороших “побочных эффектов”, с которыми мы часто сталкиваемся в функциональном программировании. Является сильная модуляризация. Вместо того чтобы подходить к разработке программного обеспечения сверху вниз. Функциональное программирование поощряет стиль программирования снизу вверх. Начните с определения модулей, которые группируют аналогичные чистые функции, которые, как вы ожидаете. Понадобятся в будущем. Затем начните писать эти маленькие, не имеющие состояния, независимые функции для создания ваших первых модулей.

По сути, мы создаем черные ящики. Позже мы свяжем вместе коробки, следуя подходу снизу вверх. Это позволяет создать прочную базу тестов, особенно модульных тестов. Которые проверяют правильность ваших чистых функций.

Как только вы доверяете своей прочной базе модулей, пришло время связать вместе модули. Этот шаг в процессе разработки также включает в себя написание интеграционных тестов для обеспечения надлежащей интеграции двух компонентов.

5 Примеров функционального программирования в Go

Чтобы нарисовать более полную картину того, как работает функциональное программирование с Go. Рассмотрим пять основных примеров.

1. Обновление строки

Это самый простой пример чистой функции. Обычно, когда вы хотите обновить строку, вы делаете следующее.

Приведенный выше фрагмент не придерживается правил функционального программирования. Поскольку переменная не может быть изменена внутри функции. Поэтому мы должны переписать фрагмент кода так, чтобы каждое значение получало свою собственную переменную.

Код гораздо более читабелен в приведенном ниже фрагменте кода.

При взгляде на нефункциональный фрагмент кода мы должны просмотреть программу, чтобы определить последнее состояниеname, чтобы найти результирующее значение для nameпеременной. Это требует больше усилий и времени, чтобы понять. Что делает функция.

2. Избегайте обновления массивов

Как было сказано ранее. Цель функционального программирования-использовать неизменяемые данные для получения нового состояния неизменяемых данных через чистые функции. Это также может быть применено к массивам, в которых мы создаем новый массив каждый раз. Когда мы хотим обновить один.

В нефункциональном программировании обновите массив следующим образом:

Давайте попробуем это в соответствии с парадигмой функционального программирования.

В примере используется исходный namesсрез в сочетании с append()функцией для добавления дополнительных значений в новый массив.

3. Избегайте обновления карт

Это несколько более экстремальный пример функционального программирования. Представьте себе, что у нас есть карта с ключом типа string и значением типа integer. На карте указано количество фруктов. Которые у нас еще остались дома. Однако мы только что купили яблоки и хотим добавить их в список.

Поскольку мы не хотим изменять исходные карты, код перебирает обе карты и добавляет значения к новой карте. Таким образом. Данные остаются неизменными.

Однако, как вы, вероятно, можете судить по длине кода, производительность этого фрагмента намного хуже. Чем простое изменяемое обновление карты. Потому что мы зацикливаемся на обеих картах. Это именно та точка. В которой вы обмениваете лучшее качество кода на производительность.

4. Функции высшего порядка и каррирование

Большинство программистов не часто используют функции высшего порядка в своем коде. Но это очень удобно для установления каррирования в функциональном программировании.

Давайте предположим. Что у нас есть простая функция. Которая складывает два целых числа. Хотя это уже чистая функция, мы хотим подробнее остановиться на этом примере, чтобы продемонстрировать. Как мы можем создать более продвинутую функциональность с помощью каррирования.

В этом случае мы можем принять только один параметр. Затем функция возвращает другую функцию в качестве замыкания. Поскольку функция возвращает замыкание, она запоминает внешнюю область видимости, содержащую начальный входной параметр.

Теперь давайте попробуем каррирование и создадим более продвинутые чистые функции.

Этот подход распространен в функциональном программировании, хотя вы не часто видите его вне парадигмы.

5. Рекурсия

Рекурсия-это программный паттерн. Который обычно используется для обхода использования циклов. Поскольку циклы всегда имеют внутреннее состояние. Чтобы знать. В каком раунде они находятся. Мы не можем использовать их в рамках парадигмы функционального программирования.

Например, приведенный ниже фрагмент кода пытается вычислить факториал для числа. Факториал-это произведение целого числа и всех целых чисел ниже него. Итак, факториал 4 равен 24 (= 4 * 3 * 2 * 1).

Обычно для этого используется цикл.

Чтобы достичь этого в рамках парадигмы функционального программирования, нам нужно использовать рекурсию. Другими словами, мы будем вызывать одну и ту же функцию снова и снова. Пока не достигнем наименьшего целого числа для факториала.

Вывод

Подведем итог тому. Что мы узнали о функциональном программировании:

  • Хотя Golang поддерживает функциональное программирование. Он не был разработан для этой цели. О чем свидетельствует отсутствие таких функций, как Map. Filter и Reduce
  • Функциональное программирование улучшает читабельность кода, поскольку функции являются чистыми и, следовательно. Простыми для понимания
  • Чистые функции легче тестировать. Так как нет внутреннего состояния. Которое может изменить вывод

Чтобы узнать больше о случаях использования чистых функций и почему они имеют значение. Ознакомьтесь с этой статьей freeCodeCamp о необходимости чистых функций для редукторов Redux.

Для получения хорошего обзора различий между функциональным. Процедурным и объектно-ориентированным программированием или если вы хотите понять. Какая парадигма подходит вам лучше всего. Я рекомендую прочитать этот проницательный пост Medium Лили Уакнин Фелсен.

LogRocket: Полная видимость ваших веб-приложений

Бесплатный Пробный баннер LogRocket Dashboard

LogRocket-это решение для мониторинга фронтендовых приложений. Которое позволяет воспроизводить проблемы так. Как если бы они происходили в вашем собственном браузере. Вместо того чтобы гадать, почему происходят ошибки, или запрашивать у пользователей скриншоты и дампы журналов. LogRocket позволяет вам воспроизвести сеанс. Чтобы быстро понять. Что пошло не так. Он отлично работает с любым приложением. Независимо от фреймворка. И имеет плагины для регистрации дополнительного контекста из Redux. Vuex и @ngrx/store.

Помимо регистрации действий и состояний Redux, LogRocket записывает консольные журналы, ошибки JavaScript, stacktraces. Сетевые запросы/ответы с заголовками + телами. Метаданные браузера и пользовательские журналы. Он также использует DOM для записи HTML и CSS на странице. Воссоздавая пиксельные видео даже самых сложных одностраничных приложений.

Попробуйте это бесплатно.

Поделитесь этим: