SlideShare ist ein Scribd-Unternehmen logo
1 von 21
Downloaden Sie, um offline zu lesen
@sixty_north
Understanding Transducers
Through Python
1
Austin Bingham
@austin_bingham
Sunday, January 25, 15
237
“Transducers are coming”
Rich Hickeyhttp://blog.cognitect.com/blog/2014/8/6/transducers-are-coming
Photo: Howard Lewis Ship under CC-BY
Sunday, January 25, 15
Functions which transform reducers
What is a transducer?
‣ Reducer (reducing function)
• Any function we can pass to reduce(reducer, iterable[, initial])
• (result, input) → result
• add(result, input)
reduce(add, [1, 2, 3], 0) → 6
‣ Transducer (transform reducer)
• A function which accepts a reducer, and transforms it in some way, and returns a
new reducer
• ((result, input) → result) → ((result, input) → result)
3
Sunday, January 25, 15
Transducers are a functional programming technique not restricted to Clojure
How does this relate to Python?
‣ Clojure implementation is the prototype/archetype
• Heavily uses anonymous functions
• Uses overloads on function arity for disparate purposes
• Complected with existing approaches
‣ Python implementation is pedagogical (but also useful)
• Explicit is better than implicit
• Readability counts!
• Has all the functional tools we need for transducers
• I’m a better Pythonista than Clojurist
4
Sunday, January 25, 15
5
Review
functional programming
tools in
Sunday, January 25, 15
6
my_filter(is_prime, my_map(prime_factors, range(32) ) )
iterable
sequence
sequence
Sunday, January 25, 15
7
def my_map(transform, iterable):
def map_reducer(sequence, item):
sequence.append(transform(item))
return sequence
return reduce(map_reducer, iterable, [])
def my_filter(predicate, iterable):
def filter_reducer(sequence, item):
if predicate(item):
sequence.append(item)
return sequence
return reduce(filter_reducer, iterable, [])
Sunday, January 25, 15
7
def my_map(transform, iterable):
def map_reducer(sequence, item):
sequence.append(transform(item))
return sequence
return reduce(map_reducer, iterable, [])
def my_filter(predicate, iterable):
def filter_reducer(sequence, item):
if predicate(item):
sequence.append(item)
return sequence
return reduce(filter_reducer, iterable, [])
reduce()
Sunday, January 25, 15
7
def my_map(transform, iterable):
def map_reducer(sequence, item):
sequence.append(transform(item))
return sequence
return reduce(map_reducer, iterable, [])
def my_filter(predicate, iterable):
def filter_reducer(sequence, item):
if predicate(item):
sequence.append(item)
return sequence
return reduce(filter_reducer, iterable, [])
reduce()
sequence.append()
Sunday, January 25, 15
7
def my_map(transform, iterable):
def map_reducer(sequence, item):
sequence.append(transform(item))
return sequence
return reduce(map_reducer, iterable, [])
def my_filter(predicate, iterable):
def filter_reducer(sequence, item):
if predicate(item):
sequence.append(item)
return sequence
return reduce(filter_reducer, iterable, [])
reduce()
sequence.append()
Empty list : ‘seed’
must be a mutable
sequence
Sunday, January 25, 15
8
>>> reduce(make_mapper(square), range(10), [])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> reduce(make_filterer(is_prime), range(100), [])
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
67, 71, 73, 79, 83, 89, 97]
‣ make_mapper() and make_filterer() are not composable
‣ to square primes we would need to call reduce() twice
‣ this requires we store the intermediate sequence
‣ the reducers returned by make_mapper() and make_filterer()
depend on the seed being a mutable sequence e.g. a list
Sunday, January 25, 15
9
(defn map
([f]
(fn [rf]
(fn
([] (rf))
([result] (rf result))
([result input]
(rf result (f input)))
([result input & inputs]
(rf result (apply f input inputs))))))
Sunday, January 25, 15
10
(defn map ;; The tranducer factory...
([f] ;; ...accepts a single argument 'f', the transforming function
(fn [rf] ;; The transducer function accepts a reducing function 'rf'
(fn ;; This is the reducing function returned by the transducer
([] (rf)) ;; 0-arity : Forward to the zero-arity reducing function 'rf'
([result] (rf result)) ;; 1-arity : Forward to the one-arity reducing function 'rf'
([result input] ;; 2-arity : Perform the reduction with one arg to 'f'
(rf result (f input)))
([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f'
(rf result (apply f input inputs))))))
Sunday, January 25, 15
11
(defn map ;; The tranducer factory...
([f] ;; ...accepts a single argument 'f', the transforming function
(fn [rf] ;; The transducer function accepts a reducing function 'rf'
(fn ;; This is the reducing function returned by the transducer
([] (rf)) ;; 0-arity : Return a 'seed' value obtained from 'rf'
([result] (rf result)) ;; 1-arity : Obtain final result from 'rf' and clean-up
([result input] ;; 2-arity : Perform the reduction with one arg to 'f'
(rf result (f input)))
([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f'
(rf result (apply f input inputs))))))
Sunday, January 25, 15
12
(defn map ;; The tranducer factory...
([f] ;; ...accepts a single argument 'f', the transforming function
(fn [rf] ;; The transducer function accepts a reducing function 'rf'
(fn ;; This is the reducing function returned by the transducer
([] (rf)) ;; 0-arity : Return a 'seed' value obtained from 'rf'
([result] (rf result)) ;; 1-arity : Obtain final result from 'rf' and clean-up
([result input] ;; 2-arity : Perform the reduction with one arg to 'f'
(rf result (f input)))
([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f'
(rf result (apply f input inputs))))))
To fully implement Clojure’s transducers in Python we also need:
‣ explicit association of the seed value with the reduction operation
‣ support for early termination without reducing the whole series
‣ reduction to a final value and opportunity to clean up state
Sunday, January 25, 15
13
class Reducer:
def __init__(self, reducer): # Construct from reducing function
pass
def initial(self): # Return the initial seed value
pass # 0-arity
def step(self, result, item): # Next step in the reduction
pass # 2-arity
def complete(self, result): # Produce a final result and clean up
pass # 1-arity
Sunday, January 25, 15
13
class Reducer:
def __init__(self, reducer): # Construct from reducing function
pass
def initial(self): # Return the initial seed value
pass # 0-arity
def step(self, result, item): # Next step in the reduction
pass # 2-arity
def complete(self, result): # Produce a final result and clean up
pass # 1-arity
new_reducer = Reducer(reducer)
Sunday, January 25, 15
13
class Reducer:
def __init__(self, reducer): # Construct from reducing function
pass
def initial(self): # Return the initial seed value
pass # 0-arity
def step(self, result, item): # Next step in the reduction
pass # 2-arity
def complete(self, result): # Produce a final result and clean up
pass # 1-arity
new_reducer = Reducer(reducer)
def transducer(reducer):
return Reducer(reducer)
Sunday, January 25, 15
13
class Reducer:
def __init__(self, reducer): # Construct from reducing function
pass
def initial(self): # Return the initial seed value
pass # 0-arity
def step(self, result, item): # Next step in the reduction
pass # 2-arity
def complete(self, result): # Produce a final result and clean up
pass # 1-arity
new_reducer = Reducer(reducer)
def transducer(reducer):
return Reducer(reducer)
⇐ two names for two concepts
Sunday, January 25, 15
Python Transducer implementations
14
Cognitect
https://github.com/cognitect-labs
PyPI: transducers
• “official”
• Python in the style of Clojure
• Only eager iterables (step back from
regular Python)
• Undesirable Python practices such as
hiding built-ins
• Also Clojure, Javascript, Ruby, etc.
Sixty North
http://code.sixty-north.com/python-
transducers
PyPI: transducer
• Pythonic
• Eager iterables
• Lazy iterables
• Co-routine based ‘push’ events
• Pull-requests welcome!
Sunday, January 25, 15
15
Thank you!
@sixty_north
Austin Bingham
@austin_bingham
http://sixty-north.com/blog/
Sunday, January 25, 15

Weitere ähnliche Inhalte

Was ist angesagt?

[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?NAVER D2
 
UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!sawat1203
 
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018 게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018 Amazon Web Services Korea
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition心 谷本
 
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門Kazuto Kusama
 
cstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLcstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLCitus Data
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングYuto Hayamizu
 
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템burnaby yang
 
Checkerboard Rendering in Dark Souls: Remastered by QLOC
Checkerboard Rendering in Dark Souls: Remastered by QLOCCheckerboard Rendering in Dark Souls: Remastered by QLOC
Checkerboard Rendering in Dark Souls: Remastered by QLOCQLOC
 
PostgreSQL High_Performance_Cheatsheet
PostgreSQL High_Performance_CheatsheetPostgreSQL High_Performance_Cheatsheet
PostgreSQL High_Performance_CheatsheetLucian Oprea
 
PostGIS 初入門應用
PostGIS 初入門應用PostGIS 初入門應用
PostGIS 初入門應用Chengtao Lin
 
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개if kakao
 
わかった気になるMySQL
わかった気になるMySQLわかった気になるMySQL
わかった気になるMySQLyoku0825
 
My sql failover test using orchestrator
My sql failover test  using orchestratorMy sql failover test  using orchestrator
My sql failover test using orchestratorYoungHeon (Roy) Kim
 
Docker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting TechniquesDocker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting TechniquesSreenivas Makam
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기Brian Hong
 
サイバーエージェントにおけるデータの品質管理について #cwt2016
サイバーエージェントにおけるデータの品質管理について #cwt2016サイバーエージェントにおけるデータの品質管理について #cwt2016
サイバーエージェントにおけるデータの品質管理について #cwt2016cyberagent
 
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte Data
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte DataProblems with PostgreSQL on Multi-core Systems with MultiTerabyte Data
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte DataJignesh Shah
 
[GitOps] Argo CD on GKE (v0.9.2).pdf
[GitOps] Argo CD on GKE (v0.9.2).pdf[GitOps] Argo CD on GKE (v0.9.2).pdf
[GitOps] Argo CD on GKE (v0.9.2).pdfJo Hoon
 

Was ist angesagt? (20)

[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!UICollectionViewLayoutでカバーフローを作りたい!
UICollectionViewLayoutでカバーフローを作りたい!
 
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018 게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018
게임을 위한 최적의 AWS DB 서비스 선정 퀘스트 깨기::최유정::AWS Summit Seoul 2018
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
 
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門
Cloud FoundryでDockerも.NETも。新しいDiegoの仕組み入門
 
cstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQLcstore_fdw: Columnar Storage for PostgreSQL
cstore_fdw: Columnar Storage for PostgreSQL
 
より深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニングより深く知るオプティマイザとそのチューニング
より深く知るオプティマイザとそのチューニング
 
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템
NDC 2017 비주얼 선택과 집중 - 3on3 아트 포스트모템
 
Checkerboard Rendering in Dark Souls: Remastered by QLOC
Checkerboard Rendering in Dark Souls: Remastered by QLOCCheckerboard Rendering in Dark Souls: Remastered by QLOC
Checkerboard Rendering in Dark Souls: Remastered by QLOC
 
PostgreSQL High_Performance_Cheatsheet
PostgreSQL High_Performance_CheatsheetPostgreSQL High_Performance_Cheatsheet
PostgreSQL High_Performance_Cheatsheet
 
PostGIS 初入門應用
PostGIS 初入門應用PostGIS 初入門應用
PostGIS 初入門應用
 
Consul
ConsulConsul
Consul
 
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
 
わかった気になるMySQL
わかった気になるMySQLわかった気になるMySQL
わかった気になるMySQL
 
My sql failover test using orchestrator
My sql failover test  using orchestratorMy sql failover test  using orchestrator
My sql failover test using orchestrator
 
Docker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting TechniquesDocker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting Techniques
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기
 
サイバーエージェントにおけるデータの品質管理について #cwt2016
サイバーエージェントにおけるデータの品質管理について #cwt2016サイバーエージェントにおけるデータの品質管理について #cwt2016
サイバーエージェントにおけるデータの品質管理について #cwt2016
 
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte Data
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte DataProblems with PostgreSQL on Multi-core Systems with MultiTerabyte Data
Problems with PostgreSQL on Multi-core Systems with MultiTerabyte Data
 
[GitOps] Argo CD on GKE (v0.9.2).pdf
[GitOps] Argo CD on GKE (v0.9.2).pdf[GitOps] Argo CD on GKE (v0.9.2).pdf
[GitOps] Argo CD on GKE (v0.9.2).pdf
 

Ähnlich wie Austin Bingham. Transducers in Python. PyCon Belarus

08-Iterators-and-Generators.pptx
08-Iterators-and-Generators.pptx08-Iterators-and-Generators.pptx
08-Iterators-and-Generators.pptxcursdjango
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Dhaval Dalal
 
Functional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smartFunctional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smartChen Fisher
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional ProgrammingFrancesco Bruni
 
python ppt.pptx
python ppt.pptxpython ppt.pptx
python ppt.pptxMONAR11
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monadsrkaippully
 
Very basic functional design patterns
Very basic functional design patternsVery basic functional design patterns
Very basic functional design patternsTomasz Kowal
 
The Challenge of Bringing FEZ to PlayStation Platforms
The Challenge of Bringing FEZ to PlayStation PlatformsThe Challenge of Bringing FEZ to PlayStation Platforms
The Challenge of Bringing FEZ to PlayStation PlatformsMiguel Angel Horna
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Samuel Fortier-Galarneau
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principlesAndrew Denisov
 
Mapfilterreducepresentation
MapfilterreducepresentationMapfilterreducepresentation
MapfilterreducepresentationManjuKumara GH
 
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologiesit-people
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicGraham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicNew Relic
 
GPars For Beginners
GPars For BeginnersGPars For Beginners
GPars For BeginnersMatt Passell
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonAnoop Thomas Mathew
 

Ähnlich wie Austin Bingham. Transducers in Python. PyCon Belarus (20)

08-Iterators-and-Generators.pptx
08-Iterators-and-Generators.pptx08-Iterators-and-Generators.pptx
08-Iterators-and-Generators.pptx
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Functional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smartFunctional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smart
 
Introduction to Functional Programming
Introduction to Functional ProgrammingIntroduction to Functional Programming
Introduction to Functional Programming
 
python ppt.pptx
python ppt.pptxpython ppt.pptx
python ppt.pptx
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
 
Very basic functional design patterns
Very basic functional design patternsVery basic functional design patterns
Very basic functional design patterns
 
The Challenge of Bringing FEZ to PlayStation Platforms
The Challenge of Bringing FEZ to PlayStation PlatformsThe Challenge of Bringing FEZ to PlayStation Platforms
The Challenge of Bringing FEZ to PlayStation Platforms
 
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.
 
Functional programming principles
Functional programming principlesFunctional programming principles
Functional programming principles
 
25-functions.ppt
25-functions.ppt25-functions.ppt
25-functions.ppt
 
Function & Recursion
Function & RecursionFunction & Recursion
Function & Recursion
 
Mapfilterreducepresentation
MapfilterreducepresentationMapfilterreducepresentation
Mapfilterreducepresentation
 
Gevent be or not to be
Gevent be or not to beGevent be or not to be
Gevent be or not to be
 
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
«Gevent — быть или не быть?» Александр Мокров, Positive Technologies
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
GPars For Beginners
GPars For BeginnersGPars For Beginners
GPars For Beginners
 
Node js
Node jsNode js
Node js
 
Thinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in PythonThinking in Functions: Functional Programming in Python
Thinking in Functions: Functional Programming in Python
 

Mehr von Alina Dolgikh

Reactive streams. Slava Schmidt
Reactive streams. Slava SchmidtReactive streams. Slava Schmidt
Reactive streams. Slava SchmidtAlina Dolgikh
 
Scala for the doubters. Максим Клыга
Scala for the doubters. Максим КлыгаScala for the doubters. Максим Клыга
Scala for the doubters. Максим КлыгаAlina Dolgikh
 
Orm на no sql через jpa. Павел Вейник
Orm на no sql через jpa. Павел ВейникOrm на no sql через jpa. Павел Вейник
Orm на no sql через jpa. Павел ВейникAlina Dolgikh
 
No sql unsuccessful_story. Владимир Зеленкевич
No sql unsuccessful_story. Владимир ЗеленкевичNo sql unsuccessful_story. Владимир Зеленкевич
No sql unsuccessful_story. Владимир ЗеленкевичAlina Dolgikh
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in PracticeAlina Dolgikh
 
Appium + selenide comaqa.by. Антон Семенченко
Appium + selenide comaqa.by. Антон СеменченкоAppium + selenide comaqa.by. Антон Семенченко
Appium + selenide comaqa.by. Антон СеменченкоAlina Dolgikh
 
Cracking android app. Мокиенко Сергей
Cracking android app. Мокиенко СергейCracking android app. Мокиенко Сергей
Cracking android app. Мокиенко СергейAlina Dolgikh
 
David Mertz. Type Annotations. PyCon Belarus 2015
David Mertz. Type Annotations. PyCon Belarus 2015David Mertz. Type Annotations. PyCon Belarus 2015
David Mertz. Type Annotations. PyCon Belarus 2015Alina Dolgikh
 
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015Alina Dolgikh
 
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015Alina Dolgikh
 
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Alina Dolgikh
 
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...Alina Dolgikh
 
Austin Bingham. Python Refactoring. PyCon Belarus
Austin Bingham. Python Refactoring. PyCon BelarusAustin Bingham. Python Refactoring. PyCon Belarus
Austin Bingham. Python Refactoring. PyCon BelarusAlina Dolgikh
 
Denis Lebedev. Non functional swift.
Denis Lebedev. Non functional swift.Denis Lebedev. Non functional swift.
Denis Lebedev. Non functional swift.Alina Dolgikh
 
Максим Лапшин. Erlang production
Максим Лапшин. Erlang productionМаксим Лапшин. Erlang production
Максим Лапшин. Erlang productionAlina Dolgikh
 
Максим Харченко. Erlang lincx
Максим Харченко. Erlang lincxМаксим Харченко. Erlang lincx
Максим Харченко. Erlang lincxAlina Dolgikh
 
Пиар в стартапе: извлекаем максимум пользы. Алексей Лартей
Пиар в стартапе: извлекаем максимум пользы. Алексей ЛартейПиар в стартапе: извлекаем максимум пользы. Алексей Лартей
Пиар в стартапе: извлекаем максимум пользы. Алексей ЛартейAlina Dolgikh
 
Подготовка проекта к первому раунду инвестиций. Дмитрий Поляков
Подготовка проекта к первому раунду инвестиций. Дмитрий ПоляковПодготовка проекта к первому раунду инвестиций. Дмитрий Поляков
Подготовка проекта к первому раунду инвестиций. Дмитрий ПоляковAlina Dolgikh
 
Как составлять правильный тизер для инвесторов? Никита Рогозин
Как составлять правильный тизер для инвесторов? Никита РогозинКак составлять правильный тизер для инвесторов? Никита Рогозин
Как составлять правильный тизер для инвесторов? Никита РогозинAlina Dolgikh
 
Startup belarus pres_khamiankova
Startup belarus pres_khamiankovaStartup belarus pres_khamiankova
Startup belarus pres_khamiankovaAlina Dolgikh
 

Mehr von Alina Dolgikh (20)

Reactive streams. Slava Schmidt
Reactive streams. Slava SchmidtReactive streams. Slava Schmidt
Reactive streams. Slava Schmidt
 
Scala for the doubters. Максим Клыга
Scala for the doubters. Максим КлыгаScala for the doubters. Максим Клыга
Scala for the doubters. Максим Клыга
 
Orm на no sql через jpa. Павел Вейник
Orm на no sql через jpa. Павел ВейникOrm на no sql через jpa. Павел Вейник
Orm на no sql через jpa. Павел Вейник
 
No sql unsuccessful_story. Владимир Зеленкевич
No sql unsuccessful_story. Владимир ЗеленкевичNo sql unsuccessful_story. Владимир Зеленкевич
No sql unsuccessful_story. Владимир Зеленкевич
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Appium + selenide comaqa.by. Антон Семенченко
Appium + selenide comaqa.by. Антон СеменченкоAppium + selenide comaqa.by. Антон Семенченко
Appium + selenide comaqa.by. Антон Семенченко
 
Cracking android app. Мокиенко Сергей
Cracking android app. Мокиенко СергейCracking android app. Мокиенко Сергей
Cracking android app. Мокиенко Сергей
 
David Mertz. Type Annotations. PyCon Belarus 2015
David Mertz. Type Annotations. PyCon Belarus 2015David Mertz. Type Annotations. PyCon Belarus 2015
David Mertz. Type Annotations. PyCon Belarus 2015
 
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
 
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015
Кирилл Борисов. Code style_checking_v2. PyCon Belarus 2015
 
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
Володимир Гоцик. Getting maximum of python, django with postgres 9.4. PyCon B...
 
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...
Андрей Солдатенко. Разработка высокопроизводительныx функциональных тестов д...
 
Austin Bingham. Python Refactoring. PyCon Belarus
Austin Bingham. Python Refactoring. PyCon BelarusAustin Bingham. Python Refactoring. PyCon Belarus
Austin Bingham. Python Refactoring. PyCon Belarus
 
Denis Lebedev. Non functional swift.
Denis Lebedev. Non functional swift.Denis Lebedev. Non functional swift.
Denis Lebedev. Non functional swift.
 
Максим Лапшин. Erlang production
Максим Лапшин. Erlang productionМаксим Лапшин. Erlang production
Максим Лапшин. Erlang production
 
Максим Харченко. Erlang lincx
Максим Харченко. Erlang lincxМаксим Харченко. Erlang lincx
Максим Харченко. Erlang lincx
 
Пиар в стартапе: извлекаем максимум пользы. Алексей Лартей
Пиар в стартапе: извлекаем максимум пользы. Алексей ЛартейПиар в стартапе: извлекаем максимум пользы. Алексей Лартей
Пиар в стартапе: извлекаем максимум пользы. Алексей Лартей
 
Подготовка проекта к первому раунду инвестиций. Дмитрий Поляков
Подготовка проекта к первому раунду инвестиций. Дмитрий ПоляковПодготовка проекта к первому раунду инвестиций. Дмитрий Поляков
Подготовка проекта к первому раунду инвестиций. Дмитрий Поляков
 
Как составлять правильный тизер для инвесторов? Никита Рогозин
Как составлять правильный тизер для инвесторов? Никита РогозинКак составлять правильный тизер для инвесторов? Никита Рогозин
Как составлять правильный тизер для инвесторов? Никита Рогозин
 
Startup belarus pres_khamiankova
Startup belarus pres_khamiankovaStartup belarus pres_khamiankova
Startup belarus pres_khamiankova
 

Kürzlich hochgeladen

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 

Kürzlich hochgeladen (20)

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Austin Bingham. Transducers in Python. PyCon Belarus

  • 1. @sixty_north Understanding Transducers Through Python 1 Austin Bingham @austin_bingham Sunday, January 25, 15
  • 2. 237 “Transducers are coming” Rich Hickeyhttp://blog.cognitect.com/blog/2014/8/6/transducers-are-coming Photo: Howard Lewis Ship under CC-BY Sunday, January 25, 15
  • 3. Functions which transform reducers What is a transducer? ‣ Reducer (reducing function) • Any function we can pass to reduce(reducer, iterable[, initial]) • (result, input) → result • add(result, input) reduce(add, [1, 2, 3], 0) → 6 ‣ Transducer (transform reducer) • A function which accepts a reducer, and transforms it in some way, and returns a new reducer • ((result, input) → result) → ((result, input) → result) 3 Sunday, January 25, 15
  • 4. Transducers are a functional programming technique not restricted to Clojure How does this relate to Python? ‣ Clojure implementation is the prototype/archetype • Heavily uses anonymous functions • Uses overloads on function arity for disparate purposes • Complected with existing approaches ‣ Python implementation is pedagogical (but also useful) • Explicit is better than implicit • Readability counts! • Has all the functional tools we need for transducers • I’m a better Pythonista than Clojurist 4 Sunday, January 25, 15
  • 6. 6 my_filter(is_prime, my_map(prime_factors, range(32) ) ) iterable sequence sequence Sunday, January 25, 15
  • 7. 7 def my_map(transform, iterable): def map_reducer(sequence, item): sequence.append(transform(item)) return sequence return reduce(map_reducer, iterable, []) def my_filter(predicate, iterable): def filter_reducer(sequence, item): if predicate(item): sequence.append(item) return sequence return reduce(filter_reducer, iterable, []) Sunday, January 25, 15
  • 8. 7 def my_map(transform, iterable): def map_reducer(sequence, item): sequence.append(transform(item)) return sequence return reduce(map_reducer, iterable, []) def my_filter(predicate, iterable): def filter_reducer(sequence, item): if predicate(item): sequence.append(item) return sequence return reduce(filter_reducer, iterable, []) reduce() Sunday, January 25, 15
  • 9. 7 def my_map(transform, iterable): def map_reducer(sequence, item): sequence.append(transform(item)) return sequence return reduce(map_reducer, iterable, []) def my_filter(predicate, iterable): def filter_reducer(sequence, item): if predicate(item): sequence.append(item) return sequence return reduce(filter_reducer, iterable, []) reduce() sequence.append() Sunday, January 25, 15
  • 10. 7 def my_map(transform, iterable): def map_reducer(sequence, item): sequence.append(transform(item)) return sequence return reduce(map_reducer, iterable, []) def my_filter(predicate, iterable): def filter_reducer(sequence, item): if predicate(item): sequence.append(item) return sequence return reduce(filter_reducer, iterable, []) reduce() sequence.append() Empty list : ‘seed’ must be a mutable sequence Sunday, January 25, 15
  • 11. 8 >>> reduce(make_mapper(square), range(10), []) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> reduce(make_filterer(is_prime), range(100), []) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] ‣ make_mapper() and make_filterer() are not composable ‣ to square primes we would need to call reduce() twice ‣ this requires we store the intermediate sequence ‣ the reducers returned by make_mapper() and make_filterer() depend on the seed being a mutable sequence e.g. a list Sunday, January 25, 15
  • 12. 9 (defn map ([f] (fn [rf] (fn ([] (rf)) ([result] (rf result)) ([result input] (rf result (f input))) ([result input & inputs] (rf result (apply f input inputs)))))) Sunday, January 25, 15
  • 13. 10 (defn map ;; The tranducer factory... ([f] ;; ...accepts a single argument 'f', the transforming function (fn [rf] ;; The transducer function accepts a reducing function 'rf' (fn ;; This is the reducing function returned by the transducer ([] (rf)) ;; 0-arity : Forward to the zero-arity reducing function 'rf' ([result] (rf result)) ;; 1-arity : Forward to the one-arity reducing function 'rf' ([result input] ;; 2-arity : Perform the reduction with one arg to 'f' (rf result (f input))) ([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f' (rf result (apply f input inputs)))))) Sunday, January 25, 15
  • 14. 11 (defn map ;; The tranducer factory... ([f] ;; ...accepts a single argument 'f', the transforming function (fn [rf] ;; The transducer function accepts a reducing function 'rf' (fn ;; This is the reducing function returned by the transducer ([] (rf)) ;; 0-arity : Return a 'seed' value obtained from 'rf' ([result] (rf result)) ;; 1-arity : Obtain final result from 'rf' and clean-up ([result input] ;; 2-arity : Perform the reduction with one arg to 'f' (rf result (f input))) ([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f' (rf result (apply f input inputs)))))) Sunday, January 25, 15
  • 15. 12 (defn map ;; The tranducer factory... ([f] ;; ...accepts a single argument 'f', the transforming function (fn [rf] ;; The transducer function accepts a reducing function 'rf' (fn ;; This is the reducing function returned by the transducer ([] (rf)) ;; 0-arity : Return a 'seed' value obtained from 'rf' ([result] (rf result)) ;; 1-arity : Obtain final result from 'rf' and clean-up ([result input] ;; 2-arity : Perform the reduction with one arg to 'f' (rf result (f input))) ([result input & inputs] ;; n-arity : Perform the reduction with multiple args to 'f' (rf result (apply f input inputs)))))) To fully implement Clojure’s transducers in Python we also need: ‣ explicit association of the seed value with the reduction operation ‣ support for early termination without reducing the whole series ‣ reduction to a final value and opportunity to clean up state Sunday, January 25, 15
  • 16. 13 class Reducer: def __init__(self, reducer): # Construct from reducing function pass def initial(self): # Return the initial seed value pass # 0-arity def step(self, result, item): # Next step in the reduction pass # 2-arity def complete(self, result): # Produce a final result and clean up pass # 1-arity Sunday, January 25, 15
  • 17. 13 class Reducer: def __init__(self, reducer): # Construct from reducing function pass def initial(self): # Return the initial seed value pass # 0-arity def step(self, result, item): # Next step in the reduction pass # 2-arity def complete(self, result): # Produce a final result and clean up pass # 1-arity new_reducer = Reducer(reducer) Sunday, January 25, 15
  • 18. 13 class Reducer: def __init__(self, reducer): # Construct from reducing function pass def initial(self): # Return the initial seed value pass # 0-arity def step(self, result, item): # Next step in the reduction pass # 2-arity def complete(self, result): # Produce a final result and clean up pass # 1-arity new_reducer = Reducer(reducer) def transducer(reducer): return Reducer(reducer) Sunday, January 25, 15
  • 19. 13 class Reducer: def __init__(self, reducer): # Construct from reducing function pass def initial(self): # Return the initial seed value pass # 0-arity def step(self, result, item): # Next step in the reduction pass # 2-arity def complete(self, result): # Produce a final result and clean up pass # 1-arity new_reducer = Reducer(reducer) def transducer(reducer): return Reducer(reducer) ⇐ two names for two concepts Sunday, January 25, 15
  • 20. Python Transducer implementations 14 Cognitect https://github.com/cognitect-labs PyPI: transducers • “official” • Python in the style of Clojure • Only eager iterables (step back from regular Python) • Undesirable Python practices such as hiding built-ins • Also Clojure, Javascript, Ruby, etc. Sixty North http://code.sixty-north.com/python- transducers PyPI: transducer • Pythonic • Eager iterables • Lazy iterables • Co-routine based ‘push’ events • Pull-requests welcome! Sunday, January 25, 15