Функциональные размышления с Julia Language — Часть I
Изучение функционального программирования с Джулией

Julia считается динамически типизированным языком общего назначения, который поддерживает несколько парадигм программирования. Строго говоря, Джулия хоть и не является языком функционального программирования (ФП), но поддерживает его.
Итак, что такое «чистый» функциональный язык программирования? Это языки, спроектированные так, чтобы иметь математические функции, использующие условные выражения и рекурсию для выполнения вычислений. Они используют неизменяемые данные, ленивые вычисления и другие конструкции для «принудительного» программирования FP. Эти языки могут быть довольно краткими и самоуверенными. Хорошим примером этого языкового класса является Haskell.
Джулия, однако, более чем счастлива дать власть программисту, вместо того, чтобы ставить ограничения и барьеры на пути, заставляющем придерживаться той или иной парадигмы.
Является ли Julia хорошим языком для функционального программирования? Я считаю, что это так. Так почему Джулия хороша в функциональном программировании? По многим причинам, включая метапрограммирование, первоклассные объекты, мощную систему типов, множественную диспетчеризацию и многие другие причины.
В последнее время ФП набирает популярность. Изменяемые состояния объектов — это новый спагетти-код, а параллелизм только добавляет сложности. FP поддерживает параллельное программирование и параллелизм, что приводит к меньшему количеству ошибок и чистому коду. В основе ФП лежат прочные математические концепции и идеи из зарождающейся математической области, известной как теория категорий.
Давайте погрузимся прямо и начнем создавать некоторые концепции.
Функциональное программирование в действии
Скажем, мне интересно узнать куб нескольких чисел, я мог бы написать:
3 * 3 * 3
2 * 2 * 2
cube(x) = *(x,x,x)
cube(x) = x * x * x
Теперь меня интересует расчет нескольких серий. Мы начнем с разработки функции для вычисления суммы целых чисел от a до b:
Теперь не будет преувеличением предположить, что в какой-то момент мне будет интересно также вычислить сумму кубов целых чисел в заданном диапазоне. В этом случае моя функция может выглядеть следующим образом:
Нетрудно заметить шаблон кода, присутствующий в двух вышеприведенных определениях функций. Еще одна подсказка — тип суммы, неявный в названии самой функции. Что нам нужно, так это другой уровень абстракции, чтобы мы могли вычислить сумму любого ряда. Нам нужно сделать тип суммы явным и передать его в качестве аргумента функции вместо жесткого кодирования в теле функции.
С приведенным выше определением функции мы делаем тип функции для суммирования явным в аргументе. Я аннотировал параметр «f», чтобы было понятно, что это функция, а не другое значение.
Теперь, если мне нужна сумма кубов от 1 до 10, я могу назвать так:
Или, если мне нужна сумма целых чисел от 1 до 10, я могу написать:
Изучение функций Джулии
В Julia функции являются объектами первого класса и могут передаваться в качестве аргументов другим функциям. Это открывает двери для еще более элегантных решений с более глубокими уровнями абстракции.
Мы можем продолжать строить абстракции поверх абстракций. Мы также можем объединять функции в цепочки. Джулия считается очень компонуемым языком. Вот когда немного знаний теории категорий может помочь вам стать лучшим программистом. Функциональное программирование имеет глубокие корни в математических основах.
В приведенном выше примере показаны эквивалентные способы объединения и составления функций вместе.
Приведенные выше примеры показывают, как передача функций в качестве аргументов может помочь нам достичь более глубоких уровней абстракции в нашем коде. Но не нужно останавливаться на достигнутом. Мы можем создавать функции, возвращаемые значения которых сами являются функциями. Возьмите следующий код в качестве примера. Рассмотрим функцию f , которая возвращает среднее значение между x и f(x) . Мы назовем эту функцию medium_damp .
julia> average_damp(square)
#7 (generic function with 1 method)
Чтобы получить среднее демпфированное значение квадратной функции при x=10 , мы вызываем with:
julia> average_damp(square)(10)
55.0

julia> dx = 0.00001;
julia> deriv(cube)(5)
75.00014999664018
Ниже приведен пример такой функции:
julia> withdraw(20)
80
julia>
julia> withdraw(20)
60
julia> withdraw(20)
40
julia> withdraw(20)
20
julia> withdraw(20)
0.0
julia>
В любом случае, в следующий раз будет больше…
Ссылки: «Структура и интерпретация компьютерных программ», Абельсон и Суссман.