Все спецпроекты
Что такое ФП ФП vs. ООП Языки ФП ФП и блокчейн Перспективы Все спецпроекты

Смена парадигмы: функциональное
программирование в блокчейн-разработке


Большинство задействованных в блокчейн-разработке языков программирования — объектно-ориентированные языки, которые входят в так называемую императивную парадигму: Solidity, Python, C++, Java. Но по мере развития блокчейн-индустрии все больше инфраструктурных проектов обращаются к так называемой декларативной парадигме, в частности — к функциональным языкам программирования. В числе таких проектов Ercoin, æternity, Arwave, Helium и другие.

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

Для этого мы ответим на вопросы:




Спонсор спецпроекта — æternity — блокчейн-платформа третьего поколения для создания децентрализованных приложений и масштабируемых смарт-контрактов. Блокчейн
æternity написан на функциональном языке программирования Erlang,
а для разработки тьюринг-полных смарт-контрактов команда проекта разработала
собственный функциональный язык Sophia. Чтобы смарт-контракты в системе могли
взаимодействовать с внешним миром, в æternity реализована система оракулов —
специальных узлов, которые получают и верифицируют информацию извне
блокчейна. Масштабируемость приложений и смарт-контрактов в сети достигается
за счет использования p2p-каналов состояний (state channels) — операция между
сторонами обрабатывается в отдельном канале, а основной блокчейн работает как
архив данных, к которому стороны обращаются в случае разногласий. Кроме того,
в æternity работает система ончейн-управления, построенная на принципах «жидкой
демократии» (liquid democracy).

Присоединиться к русскоязычному сообществу проекта:

В сотрудничестве с æternity мы готовим еще несколько интересных спецпроектов.

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

Функциональное программирование (ФП) — декларативная парадигма
программирования
. Ее обычно противопоставляют более известной
альтернативе — императивной парадигме программирования, в частности —
объектно-ориентированному программированию (ООП). ФП — это подход
к разработке компьютерных программ, в котором основной инструмент —
математические функции. Причем речь идет о чистых функциях, чей результат
зависит исключительно от вводных данных.


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


С другой стороны, возраст
человека не будет чистой
функцией. Время идет, а ответ
будет меняться в зависимости
от того, когда вы спросите.
Функция «возраст» меняет
значение из-за побочного
эффекта
 — хода времени.

Функциональное программирование построено на основе
лямбда-исчисления — формальной системы, изобретенной
американским математиком Алонзо Черчем
в 1930-х годах для исследования проблем вычислимости.

Алонзо Черч (1903‐1995)

Формальная система Черча основывается на двух принципах:

1. Все используемые функции — чистые и выдают один и тот же
результат для тех же вводных данных.
2. Каждая функция интерпретируется как «черный ящик». Мы не 
можем знать, что происходит внутри функции, и видим только
вводные данные и результат.

В лямбда-исчислении задействованы два основных типа сущностей:

1. Функции, которые для простоты обозначают греческой буквой 𝜆
(отсюда название). Буква лямбда — просто способ сказать
«функция» короче.
2. Аргументы, к которым применяются функции. Аргумент
может быть числом или даже другой функцией с собственными
аргументами.


Лямбда-исчисление оставалось набором теоретических идей и не было полностью
применимо к проблемам и ограничениям реального мира. Однако в 1958
информатик из MIT Джон МакКарти представил язык List Processing, также известный
как Lisp. Этот язык программирования происходил из лямбда-исчисления и обладал
многими свойствами функциональных языков программирования. Теперь Lisp
считается прародителем функциональных языков.


Алан Тьюринг (1912‐1954)

Занимательный факт: Черч работал над лямбда-
исчислением в Принстонском университете и был научным
руководителем отца информатики Алана Тьюринга. Оба
интересовались исследованиями математической логики
вычислений. Пока Алонзо Черч подходил к исследованиям
со стороны чистых функций, Тьюринг разрабатывал то, что
мы теперь называем машиной Тьюринга — математическую
модель вычислений, в которой воображаемая машина
манипулирует символами на ленте, согласно набору правил.


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


Машина Тьюринга способна имитировать любой компьютерный алгоритм,
а лямбда-исчисление Черча позволяет имитировать любую машину Тьюринга.
Учитель и ученик просто подошли к одному и тому же вопросу с разных сторон.

В чем разница между функциональным
программированием и другими стилями
программирования?

Самый прямой способ познакомиться с основными чертами функционального
программирования — сравнить декларативную парадигму с императивными
языками и, в частности, объектно-ориентированным программированием.

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

Представьте, что нам нужно отправить бумажное письмо Альберту. Вот как
выглядели бы инструкции для машины в императивном стиле:


1. Возьми лист бумаги и ручку вон там. 2. Возьми конверт вон там.

4. Сложи лист пополам. 3. Напиши «Привет, Альберт!» на листе бумаги.

5. Возьми конверт вон там. 6. Напиши адрес Альберта на конверте.

8. Запечатай конверт. 7. Положи лист бумаги в конверт.

1. Возьми лист бумаги и ручку вон там.

2. Возьми конверт вон там.

3. Напиши «Привет, Альберт!» на листе бумаги.

4. Сложи лист пополам.

5. Возьми конверт вон там.

6. Напиши адрес Альберта на конверте.

7. Положи лист бумаги в конверт.

8. Запечатай конверт.


Звучит утомительно, но вполне понятно, если машина знает адрес Альберта и слова,
которые мы используем.

Аналогичное задание на функциональном языке выглядело бы как-то так:

Письмо   это запечатанный конверт с адресом Альберта с сообщением внутри.
Сообщение   это лист бумаги, на котором написан текст.
Текст: «Привет, Альберт».

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



Объектно-ориентированное
программирование
объединяет данные и процедуры с ними в объекты.
Функциональное программирование разграничивает данные и функции.

Объектно-ориентированное программирование объединяет данные и процедуры с ними
в объекты.
Функциональное
программирование
разграничивает данные
и функции.

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


В объектно-ориентированном
программировании
посредством методов можно
присваивать новые значения
переменным.
Функциональное
программирование
просто связывает вводные
данные с определенным
результатами. Значения
переменных объявляются
один раз и больше
не меняются.

В объектно-ориентированном программировании посредством методов можно присваивать новые значения переменным. Функциональное программирование просто связывает вводные данные с определенным результатами. Значения переменных объявляются один раз и больше не меняются.

И в ООП, и в ФП есть переменные. В ООП переменные по-настоящему переменные,
то есть их значение может меняться. В ФП переменные больше похожи на 
переменные в математике, где х это — просто имя для конкретного значения, как х=2.

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


В ООП процедуры могут
вызвать побочные эффекты в нелокальных переменных.
В ФП функции, как правило, не имеют неожиданных
побочных эффектов.


В ООП процедуры могут вызвать побочные эффекты в нелокальных переменных. В ФП функции как правило не имеют неожиданных побочных эффектов.

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

Почему блокчейн-проекты
используют функциональные языки
программирования?

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


Отличный пример этих преимуществ — Erlang, функциональный язык
программирования, разработанный Джо Армстронгом, Робертом Вирдингом
и Майком Уильямсом в 1986. Этот язык позволяет разработчикам обновлять
или иначе изменять код в работающей системе «по-горячему», не  останавливая
систему. Erlang особенно подходит для блокчейн-разработки и создания
отказоустойчивых систем.

Какие функциональные языки самые
популярные? Какие из них используются
в блокчейн-программировании?

Большинство современных языков программирования — мультипарадигменные.
У них есть свойства объектно-ориентированных языков, функциональных языков
и других парадигм. Среди чисто функциональных языков программирования самые
представленные — Haskell и Elm. Популярные функциональные языки с элементами
других парадигм: OCaml, Erlang, Elixir, Scala, F#, Clojure, Scheme.

Блокчейн-проекты используют некоторые функциональные языки для создания
блокчейн-протоколов и смарт-контрактов. Среди таких языков: Haskell, OCaml, Erlang,
Sophia и Elixir.


Блокчейн-платформа для распределенных приложений и смарт-контрактов
æternity использует языки Erlang, Sophia и Elixir. Блокчейн-протокол
написан с нуля на Erlang, а для смарт-контрактов используется специально
разработанный для æternity функциональный язык Sophia. Elixir, производный
язык, схожий с Erlang, используется для обучения новых разработчиков.
В команду æternity входит один из создателей Erlang Роберт Вирдинг,
Ульф Норелл, Тобиас Эрик и другие эксперты с сотней лет общего опыта в ФП.

Присоединиться к русскоязычному сообществу проекта:

Что разработчику децентрализованных
приложений нужно знать
о функциональном программировании?

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

Другой важный момент — писать программы на функциональных языках безопаснее
из-за отсутствия побочных эффектов. Для математических
расчетов и распределенных вычислений функциональный код может быть короче,
чем аналоги на языках ООП. Кроме того, некоторые функциональные языки,
например, Erlang, позволяют разработчикам менять код «на ходу» без перезагрузки
или отключения системы.

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



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

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

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

Подписывайтесь на рассылку
и не пропускайте новые спецпроекты

Автор — Кшиштоф Шпак
Редактор — Татьяна Оттер
Дизайнер и иллюстратор — Зара Аракелян
Проектный менеджер — Константин Голубев
Руководитель — Влад Лихута