Александр Щепановский «Почему каждому языку нужен...
DESCRIPTION
Такие библиотеки как funcy и underscore часто связывают с функциональным программированием, но настоящий их фокус - это практичность. Задача их - упростить манипулирование данными, коллекциями, функциями и даже потоком управления, а также абстрагировать часто встречащиеся полезные поведения. В своём докладе я приведу жизненные примеры использования всего этого, а также расскажу об идеях заложенных в и продвигаемых funcy.TRANSCRIPT
![Page 1: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/1.jpg)
Почему каждому языку нужен свой _
![Page 2: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/2.jpg)
Что такое _?
Underscore – библиотека для JavaScript, которая делает жизнь лучше, предоставляя кучу полезных утилит.
![Page 3: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/3.jpg)
Что такое funcy?
funcy – библиотека для Python, ...
![Page 4: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/4.jpg)
Запутанный кусок кода
images = []
for url in urls:
for attempt in range(TRIES):
try:
images.append(download_image(url))
break
except HttpError:
if attempt + 1 == TRIES:
raise
![Page 5: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/5.jpg)
Распутанный кусок кода
http_retry = retry(TRIES, HttpError)
harder_download = http_retry(download_image)
images = map(harder_download, urls)
![Page 6: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/6.jpg)
Словарь с грязными данными
d = {}
for k, v in request.items():
try:
d[k] = int(v)
except (TypeError, ValueError):
d[k] = None
![Page 7: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/7.jpg)
Словарь с грязными данными
walk_values(silent(int), request)
![Page 8: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/8.jpg)
Отслеживание предыдущего элемента
prev = None
is_ascending = True
for x in seq:
if prev and x >= seq:
is_ascending = False
break
prev = x
![Page 9: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/9.jpg)
Отслеживание предыдущего элемента
is_ascending = all(l < r for l, r
in pairwise(seq))
![Page 10: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/10.jpg)
Больше кода
● Дольше писать● Дольше читать● Дольше отлаживать● Больше ошибок
![Page 11: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/11.jpg)
Зачем нужен _
● ...● …● …● ...
![Page 12: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/12.jpg)
Запутанный кусок кода
images = []
for url in urls:
for attempt in range(TRIES):
try:
images.append(download_image(url))
break
except HttpError:
if attempt + 1 == TRIES:
raise
![Page 13: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/13.jpg)
Что здесь происходит?
● Загрузка картинок (полезный экшн)● Повторные попытки загрузки● Итерация по адресам и сбор результатов
![Page 14: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/14.jpg)
Запутанные аспекты
images = []
for url in urls:
for attempt in range(TRIES):
try:
images.append(download_image(url))
break
except HttpError:
if attempt + 1 == TRIES:
raise
![Page 15: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/15.jpg)
Выделим повторные попытки
def retry(...):
...
http_retry = retry(TRIES, HttpError)
harder_download = http_retry(download_image)
images = []
for url in urls:
images.append(harder_download(url))
![Page 16: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/16.jpg)
Свернём итерацию
def retry(...):
...
http_retry = retry(TRIES, HttpError)
harder_download = http_retry(download_image)
images = map(harder_download, urls)
![Page 17: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/17.jpg)
Вынесем полезные шаблоны
● retry – в библиотеку● map – стандартная функция
(но если нет, то тоже в библиотеку)
![Page 18: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/18.jpg)
Зачем нужен _
● содержит общие шаблоны● …● …● ...
![Page 19: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/19.jpg)
Словарь с грязными данными
# вариант с циклом
d = {}
for k, v in request.items():
try:
d[k] = int(v)
except (TypeError, ValueError):
d[k] = None
# вариант с функцией
walk_values(silent(int), request)
![Page 20: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/20.jpg)
Упрощённый вариант
# вариант с функцией
walk_values(int, request)
# вариант с генератором списков
{k: int(v) for k, v in request.items()}
![Page 21: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/21.jpg)
Составляющие компоненты
# 3 составляющих
walk_values(int, data)
# около 8 составляющих
{k: int(v) for k, v in data.items()}
![Page 22: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/22.jpg)
Высокий и низкий уровень
walk_values(int, data)
# красным выделены низкоуровневые детали
{k: int(v) for k, v in data.items()}
![Page 23: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/23.jpg)
Зачем нужен _
● содержит общие шаблоны● скрывает низкоуровневые детали● …● ...
![Page 24: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/24.jpg)
Естественный язык
# строю словарь из пар
# ключ-"значение, приведённое к целому числу"
# для каждой пары ключ-значение данного словаря
{k: int(v) for k, v in request.items()}
# привожу значения словаря к целым числам
walk_values(int, request)
![Page 25: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/25.jpg)
Зачем нужен _
● содержит общие шаблоны● скрывает низкоуровневые детали● подстёгивает мышление на более абстрактном уровне● ...
![Page 26: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/26.jpg)
Отслеживание предыдущего элемента
is_ascending = all(l < r for l, r
in pairwise(seq))
![Page 27: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/27.jpg)
Порождение новых понятий
is_ascending = all(l < r for l, r
in pairwise(seq))
последовательность возрастает, если для всех её соседних пар левый сосед меньше правого.
![Page 28: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/28.jpg)
Зачем нужен _
● содержит общие шаблоны● скрывает низкоуровневые детали● подстёгивает мышление на более абстрактном уровне● предоставляет набор высокоуровневых понятий
![Page 29: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/29.jpg)
Библиотеки
JavaScript – Array, Function, Underscore, Lo-Dash
![Page 30: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/30.jpg)
Библиотеки
JavaScript – Array, Function, Underscore, Lo-Dash
Python – itertools, functools, funcy, toolz, fn.py
![Page 31: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/31.jpg)
Библиотеки
JavaScript – Array, Function, Underscore, Lo-Dash
Python – itertools, functools, funcy, toolz, fn.py
Ruby – Enumerable, ActiveSupport
![Page 32: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/32.jpg)
Библиотеки
JavaScript – Array, Function, Underscore, Lo-Dash
Python – itertools, functools, funcy, toolz, fn.py
Ruby – Enumerable, ActiveSupport
PHP – functional-php, Underscore.php
![Page 33: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/33.jpg)
Библиотеки
JavaScript – Array, Function, Underscore, Lo-Dash
Python – itertools, functools, funcy, toolz, fn.py
Ruby – Enumerable, ActiveSupport
PHP – functional-php, Underscore.php
Clojure – clojure.core
![Page 34: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/34.jpg)
Ещё библиотеки
Java – FunctionalJava, lambdaj
![Page 35: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/35.jpg)
Ещё библиотеки
Java – FunctionalJava, lambdaj
C# - LINQ
![Page 36: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/36.jpg)
Ещё библиотеки
Java – FunctionalJava, lambdaj
C# - LINQ
Objective-C – Underscore.m
![Page 37: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/37.jpg)
Зачем нужен _
● содержит общие шаблоны● скрывает низкоуровневые детали● подстёгивает мышление на более абстрактном уровне● предоставляет набор высокоуровневых понятий
![Page 38: Александр Щепановский «Почему каждому языку нужен свой _»](https://reader034.vdocuments.pub/reader034/viewer/2022052412/557cb1ead8b42a1b0c8b458d/html5/thumbnails/38.jpg)
Спасибо
hackflow.comgithub.com/Suor@hackflow