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

Почему так много шумихи?

Функциональное программирование — не новая тема, его концепции были в мире программирования с 1950-х годов с Алонзо Черчем и его лямбда-исчислением, но что заставляет парадигму из 50-х годов создавать столько шумихи в наши дни? Ну, я считаю, что вся эта шумиха из-за трех основных причин:

— Компиляторы

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

— Вычислительная мощность

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

Многоядерное программирование на императивных языках — непростая задача, потому что я разделяю и изменяю состояния. Я не могу просто запускать несколько экземпляров моей программы по одному на каждом ядре и надеяться, что она будет работать безопасно и лаконично, из-за совместного использования состояний теперь у меня есть несколько программы, пытающиеся получить доступ к одним и тем же точкам в памяти в одно и то же время, и это создает условия гонки, делая мою программу небезопасной и рискуя скомпрометировать данные и/или выполнение программы.

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

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

Если вы не делитесь своими состояниями и не изменяете их, вы можете гарантировать безопасность и безопасный параллелизм.

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

— Память

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

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

Зачем изучать функциональное программирование?

Ну, функциональное программирование — очень замечательная тема, вдохновленная лямбда-исчислением и математикой, и для меня это суть начала определений вычислений, а не просто очень увлекательная тема, каждый год создается все больше и больше функциональных языков, как правило, по мере того, как диалект lisp или ml и языки прошлого, которые очень хорошо адаптировались к нашим текущим потребностям, такие как Erlang, Haskell, наконец-то получают свое место под солнцем, и, конечно же, императивные языки (java, python, JS) добавляют все больше и больше функциональных возможностей. к их синтаксису и программному обеспечению недавно добавлены лямбда-функции Excel, помогающие в создании листов.

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