Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Functional programming for beginners
Search
Sobolev Nikita
March 22, 2020
Programming
0
270
Functional programming for beginners
Sobolev Nikita
March 22, 2020
Tweet
Share
More Decks by Sobolev Nikita
See All by Sobolev Nikita
PythoNN – Александр Гончаров
sobolevn
0
49
PythoNN – Андрей Пронин
sobolevn
0
94
PythoNN: Василий Рябов – "Парсинг бинарных данных с помощью ctypes, или пишем на питоне как на Си"
sobolevn
0
200
GitHub Planet - OpenSource
sobolevn
0
240
Polymorphism and Typeclasses
sobolevn
2
130
New GitHub Features
sobolevn
0
62
Problems of static analysis in Python
sobolevn
0
130
Announcing typed-linter
sobolevn
0
220
About GitHub Stars
sobolevn
0
180
Other Decks in Programming
See All in Programming
Google Cloudとo11yで実現するアプリケーション開発者主体のDB改善
nnaka2992
0
100
Honoとフロントエンドの 型安全性について
yodaka
7
1.5k
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.6k
The Clean ArchitectureがWebフロントエンドでしっくりこないのは何故か / Why The Clean Architecture does not fit with Web Frontend
twada
PRO
51
16k
Rails 1.0 のコードで学ぶ find_by* と method_missing の仕組み / Learn how find_by_* and method_missing work in Rails 1.0 code
maimux2x
1
260
Jakarta EE meets AI
ivargrimstad
0
650
CDKを使ったPagerDuty連携インフラのテンプレート化
shibuya_shogo
0
120
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
9
2.6k
Rubyと自由とAIと
yotii23
6
1.9k
データベースのオペレーターであるCloudNativePGがStatefulSetを使わない理由に迫る
nnaka2992
0
250
Kotlinの開発でも AIをいい感じに使いたい / Making the Most of AI in Kotlin Development
kohii00
5
1.8k
技術を改善し続ける
gumioji
0
180
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
91
5.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
660
The Cost Of JavaScript in 2023
addyosmani
47
7.4k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
A designer walks into a library…
pauljervisheath
205
24k
Statistics for Hackers
jakevdp
797
220k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
YesSQL, Process and Tooling at Scale
rocio
172
14k
For a Future-Friendly Web
brad_frost
176
9.6k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
Transcript
Никита Соболев github.com/sobolevn
>_ X Функциональное программирование для новичков
Проблемы определений
Проблемы определений > Функциональный стиль / императивный стиль
Проблемы определений > Функциональный стиль / императивный стиль > Способ
проверки типов: до / во время работы
Проблемы определений > Функциональный стиль / императивный стиль > Способ
проверки типов: до / во время работы > Изменяемые / неизменяемые структуры данных
Проблемы определений > Функциональный стиль / императивный стиль > Способ
проверки типов: до / во время работы > Изменяемые / неизменяемые структуры данных > Поддержка языка
Проблемы определений > Функциональный стиль / императивный стиль > Способ
проверки типов: до / во время работы > Изменяемые / неизменяемые структуры данных > Поддержка языка > Стиль для низкого уровня программирования
Но на самом деле!
def sum_numbers(numbers): ... def generate_numbers(count): ... print(sum_numbers(generate_numbers(5)))
None
Композиция
None
❌ ❌
= типы
А что у нас с типизацией?
А что у нас с типизацией? > С попытками приведения
/ без console.log(1 + 'a')
А что у нас с типизацией? > С попытками приведения
/ без console.log(1 + 'a') > Проверка до выполнения / проверка во время выполнения
А что у нас с типизацией? > С попытками приведения
/ без console.log(1 + 'a') > Проверка до выполнения / проверка во время выполнения > Явные аннотации / скрытые типы
Явная типизация позволяет нам по одному объявлению функции узнать о
ней все!
def sum_numbers(numbers): ... def generate_numbers(count): ... print(sum_numbers(generate_numbers(5)))
def sum_numbers(numbers: List[int]) -> int: ... def generate_numbers(count: int) ->
List[int]: ... print(sum_numbers(generate_numbers(5)))
>_ X Практика
dry-python/returns Делаем неявное – явным 16 github.com/dry-python/returns
{"a": 1}.get(by_key)
None
None
Input -> или
Result[, ] если = значение = ошибка
Maybe[] если = None
Callable[[List[int]], List[str]] 23
Callable[[List[int]], List[str]] • Выбросит ли она исключение? Да? Result[List[int], Exception]
23
Callable[[List[int]], List[str]] • Выбросит ли она исключение? Да? Result[List[int], Exception]
• Является ли наша функция чистой? Нет? IO[List[int]] 23
Callable[[List[int]], List[str]] • Выбросит ли она исключение? Да? Result[List[int], Exception]
• Является ли наша функция чистой? Нет? IO[List[int]] • Все вместе? Конечно! IOResult[List[int], Exception] 23
И более удобная композиция compose, pipe, flow, bind, pipeline, lift
24
None
= типы
27 def get_user(user_id: int) -> IOResultE['User']: return _parse_json(_make_request(user_id)) # BOOM
def _make_request(user_id: int) -> IOResultE[Response]: ... def _parse_json(response: Response) -> ResultE['User']: ...
None
29 def get_user(user_id: int) -> IOResultE['User']: return IOResult.lift_result( _parse_json, )(_make_request(user))
def _make_request(user_id: int) -> IOResultE[Response]: ... def _parse_json(response: Response) -> ResultE['User']: ...
30 def get_user(user_id: int) -> IOResultE['User']: return flow( user_id, _make_request,
IOResult.lift_result(_parse_json), ) @impure_safe def _make_request(user_id: int) -> Response: ... @safe def _parse_json(response: Response) -> 'User': ...
А что если функция зависит от текущего контекста? RequiresContext[Env, Result]
А что если функция асинхронная?
dry-python/returns Делаем неявное – явным 33 github.com/dry-python/returns
Полезные ссылки • https://sobolevn.me/2019/02/python-exceptions- considered-an-antipattern • https://sobolevn.me/2020/02/typed-functional- dependency-injection 34
t.me/ opensource_findings 35
Вопросы? github.com/sobolevn sobolevn.me 36