Функциональные размышления с Julia Language — Часть I

Dec 01 2022
Изучение функционального программирования с Джулией Джулия считается универсальным динамически типизированным языком, который поддерживает несколько парадигм программирования. Строго говоря, Джулия хоть и не является языком функционального программирования (ФП), но поддерживает его.

Изучение функционального программирования с Джулией

Изображение автора

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>

В любом случае, в следующий раз будет больше…

Ссылки: «Структура и интерпретация компьютерных программ», Абельсон и Суссман.