1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
#+TITLE: Алексей Пирогов про ФП
#+DATE: <2019-03-22 Пт>
#+LANGUAGE: ru
* Алексей Пирогов про ФП
Алексей Пирогов провел вебинар на тему «Функциональное
программирование как парадигма: цели, способы, применимость». Вебинар
был транслирован на YouTube-канале Hexlet, автоматизированной площадке
обучающей программированию.
Алексей Пирогов — хаскеллист, в прошлом питонист. Недавно он пополнил
ряды преподавателей Hexlet и теперь готовит курс по Python на этой
площадке. Он сделал мини-курс на [[https://code-basics.ru/languages/python][Code-Basics]]. Имеет канал в [[https://t.me/brain%255Fdump%255Fetc][Telegram]] и
на [[https://www.youtube.com/channel/UCXk1kxTjZwluYLyijyKVsAA][Youtube]], а также он является соорганизатором [[http://prog.msk.ru/][«Клуба Программистов в
Москве»]]. В [[https://hexlet-ru.slack.com/][слак-канале Hexlet]] Алексея можно найти под ником @astynax.
in:0GX4JRAGEzc
Этот вебинар рассматривает тему обзорно. Он будет полезен тем, кто не
знает, что такое ФП и зачем оно существует или знает о нем
недостаточно много. Далее представляю набор ключевых идей с
трансляции. Информация в том или ином виде сказана на трансляции.
** Что такое ФП
/Функциональное программирование/ — это отделение чистого кода от кода
с побочными эффектами.
Чистые функции похожи на функции из математики. Они возвращают всегда
один и тот же результат при одинаковых аргументах. Это их главное
свойство. Они не затрагивают все то, что находится за их телом. Не
пишут в консоль, не трогают БД, не генерят случайные числа.
Функция, которая оперирует с “внешним миром”, то есть вне своего тела,
производит /побочные эффекты/. Побочные эффекты, они же сайд-эффекты,
это как правило операции ввода-вывода, хождение в сеть, диск. Эти
операции возможно делать в небольших участках программы, а логику
описывать функционально.
В языках с единственной доступной парадигмой функционального
программирования есть четкое разделение чистого кода от
нечистого. Такое разделение всячески поощряется. В большинстве языков
с элементами функционального программирования нельзя проверить
является ли функция чистой или нет.
** Ключевые свойства
- Функции высшего порядка
- Иммутабельные структуры данных
/Функции высшего порядка/ — возможность возвращать и передавать функцию
в качестве аргумента.
/Имутабельные структуры данных/ — данные, которые нельзя изменить на
уровне языка. Оперируя над такими данными, мы не можем изменить саму
структуру, а можем вернуть новую версию этой структуры. Иммутабельные
структуры данных реализованы везде по-разному. В современных
компиляторах они оптимизированы и работают быстро.
** Чистый код просто:
- Анализировать :: Самое важное свойство ФП — способность
рассуждать о функциях. Человеку легче
оперировать с тем, что находится вблизи него. В
ФП легче держать весь контекст функции в
голове. Не надо думать о глобальных переменных,
которые могут быть изменены после вызова
функции. Посмотрев тело функции, можно легко
понять все, что с ней происходит.
- Тестировать :: Тут все просто. Если мы знаем, что функция всегда
возвращает одинаковое значение при одинаковых
аргументах — значит ее легче тестировать. Не
нужно учитывать внешний мир, от которого она
может зависеть.
- Переиспользовать :: Чистый код легко переиспользовать, потому
что мы можем код спокойно копировать. Он не зависит от
контекста.
- Вычислять параллельно и/или конкурентно :: Большинство проблем
при запуске параллельных функций связаны с разделением
данных, которые изменяются. Мы вынуждены делать семафоры,
локи и так далее, потому что у нас есть процессы, которые
могут менять общие данные произвольно. \\ \\
В чистых функциях, работающих с иммутабельными структурами
данных нет таких проблем. Мы можем отдать структуру десяти
разным процессам и они ее не смогут поменять.
** Удобно писать
- Компиляторы, парсеры, генераторы чего-либо
- Сложную логику, ложащуюся на DSL (Например Sigma)
- Высококонкурентный код (Например код на Erlang)
- GUI (Например React)
** Как научиться
Чтобы научиться настоящему ФП, нужно изучить Haskell.
** Почему Haskell?
Haskell – чистый функциональный язык, который позволяет изучить ФП как
подход и писать идиоматический для ФП код. Есть другой вариант для
изучения, например Standart ML, но этот язык мертвый. Haskell же хорош
тем, что у него есть живое сообщество. Помимо этого Haskell —
статически-типизированный язык, который заодно научит интересному
подходу к типам, отличающегося от типов в других языках.
Функциональное программирование можно изучить в вузе под руководством
преподавателя на каком-то другом языке, хоть на Python. Но здесь
потребуется именно преподаватель.
Фишка брать функциональный язык в том, что мы не сможем схалявничать и
использовать старые знакомые нам подходы. Уроки, которые мы получим
изучив Haskell, могут быть применены в повседневной жизни потом, вне
зависимости от языка программирования.
** Теория категорий
Есть такой миф, что в Haskell не стоит лезть, если не знаешь теорию
категорий. Это неправда. Я из теории категорий примерно знаю
содержание первых двух страниц типичной книги и это мне это не мешает
писать production-код на Haskell.
Теория категорий — это приятная штука для развития мозгов в первую
очередь, она даже не про программирование. Она может помочь стать
лучше как программист, а может и не помочь.
** Что еще из языков
- Clojure :: Потому что современный живой лисп в функциональной
парадигме.
- Erlang :: Erlang — не язык, который создавался, чтобы быть
функциональным, а создавался для того, чтобы быть
надежным. Функциональная парадигма в нем применяется,
чтобы создавать устойчивые к отказам программы. Поэтому
в языке не очень хорошо с выразительностью. \\ \\
После Erlang можно пописать на Elixir. Он похож на Ruby
с рельсами.
** Про парадигмы
Существует мнение, что стоит изучать по одной новой парадигме в
год. Изучать их нужно на максимально ярких для этих парадигм
языках. Хотим изучить ФП — берем Haskell. Хотим изучить ООП — берем
SmallTalk. Хотим изучить Мета-программирование — берем лиспы. Хотим
логическое программирование — берем Prolog.
Какая парадигма лучше всего? Никакая, все парадигмы клевые.
Изучать новые парадигмы всегда сложно, но это интересно. Чем больше мы
сформируем отличных друг от друга навыков, тем будем ценнее вне
зависимости от того, что мы будем делать. Это происходит, потому что
разные парадигмы позволяют нам бо́льшими способами решить задачу.
** Для каких задач не подходит ФП
Функциональные языки общего назначения являются версиями
лямбда-исчислений. Так как мы знаем, что лямбда-исчисление может
выразить любую вычислительную задачу, на ФП языке мы можно решить
любую задачу.
Функциональные языки хорошо себя чувствуют в тех областях, где можно
использовать много памяти. Потому ФП не подходит для встраиваемых
систем и всему тому, что должно быть близко к железу.
** О типизации
Лямбда-исчисление как таковое является безтиповым. Все типы — это
хитро-сделанные функции в оригинальном лямбда-исчислении.
Очень круто пописать на типизированных функциональных языках. Если я
знаю, что в функцию будут приходить только строчки, а выходить только
числа, то это позволяется мне проще рассуждать о функции. Не нужно
думать, что придет что-то не то.
Также круто пописать на динамически-типизированных языках. Например
Clojure.
** Про работу
Все люди, которых я знаю, если хотят писать на Haskell, то пишут на
Haskell за деньги. Люди, которые ищут отговорки, продолжают писать на
чем-то ином. Я в этом убежден. Работа есть.
Если технология не мертва, значит она кому-то нужна.
Сейчас, когда можно работать удаленно, найти работу по Haskell не
составляет сложности. Если ты вчерашний студент, можно очень круто
устроиться. Раз в полгода приходят вакансии от Tesla идти в
магистратуру в Штаты, чтобы потом писать на Haskell ПО, которое
анализирует метрики приходящие с автомобиля.
** Ответы на вопросы
*** Lisp — функциональный язык
Это неправда. Лисп — не функциональный язык. Код на лиспе содержит
присваивание и измененных структур данных. Это процедурный код.
SICP — это не книжка по функциональному программированию. Она
использует некоторые моменты, свойственные ФП. Это книга про
информатику в общем. В самой книге присутствуют термин “Процедура”, а
не “Функция”.
Clojure — это Lisp-подобный язык, но функциональный. Clojure
вдохновлялась Lisp’ом на этапе зарождения концепций, но в отличии от
него это functional-first язык. Все структуры данных
иммутабельные. Разделения на чистые и грязные функции там нет, тем не
менее в нем отсутствует практика злоупотреблять побочными эффектами.
*** Применяются ли ФП-элементы в Python
Применяются, но в Python принято их избегать
исторически. Использование только map, filter, reduce не делает код
функциональным. Это синтаксический сахар для пайплайнов, которые их
обрабатывают.
*** ООП vs ФП
Нельзя сказать что ООП очень сильно противоречит ФП. Они про
разное. Они не противоположны, они ортогональны. Что важнее для
создания продукта парадигма языка или библиотеки?
Библиотеки, конечно же, важны, но приходится и самому писать
код. Лучше писать код, понимая, что ты делаешь. Порой сами библиотеки
могут быть плохо спроектированы и вам придется самому что-то
писать. Лучше иметь возможность смотреть на задачу шире.
Если вдруг у кого-то работа связана только со склеиванием библиотек и
не приходится писать свой код, то не важно какая парадигма будет
использована. Но такое происходит редко.
** Материалы для изучения
- [[https://www.manning.com/books/exploring-haskell][Книга Exploring Haskell]]
- [[https://stepik.org/course/75/][Курс по Haskell на Stepic]]
- [[https://www.ohaskell.guide/][Книга О Haskell по-человечески]]
** Задачи
- [[https://www.codewars.com/][Codewars]]
- [[http://www.4clojure.com/][4clojure]]
** Другие ссылки
- [[https://www.meetup.com/Moscow-Clojure-Script-Meetup/][Clojure DOJO]]
- [[https://t.me/haskellru][Сообщество Haskell в Telegram]]
** Заключение
На стриме присутствовали звуковые искажения, которые порой
останавливали повествование Алексея. Надеюсь что-нибудь с этим
сделают. Помимо этого у Натальи, представляющей докладчика ведущей, на
записи присутствовало эхо.
Тем не менее спасибо Алексею и команде Hexlet за вебинар. Человека для
создания курса по питону наверное лучше не найти, с нетерпением жду
нового материала от него. Было бы круто дополнить раздел с книгами.
|