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
Snake Snacks: Function Composition, The Dumb Way
Search
Brian Hicks
September 07, 2017
Technology
170
0
Share
Snake Snacks: Function Composition, The Dumb Way
Brian Hicks
September 07, 2017
More Decks by Brian Hicks
See All by Brian Hicks
Esperanto
brianhicks
0
150
Make Snacks: Yet Another JavaScript Build System
brianhicks
0
130
State of Elm 2017
brianhicks
1
570
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
470
Terraform All The Things!
brianhicks
2
420
Kubernetes for the Mesos User
brianhicks
1
120
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
580
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
150
Other Decks in Technology
See All in Technology
ハーネスエンジニアリングをやりすぎた話 ~そのハーネスは解体された~
gotalab555
4
1.7k
プラットフォームエンジニアリングの実践 - AWS コンテナサービスで構築する社内プラットフォーム / AWS Containers Platform Meetup #1
literalice
1
160
AIはハッカーを減らすのか、増やすのか?──現役ホワイトハッカーから見るAI時代のリアル【MEGU-Meet】
cscengineer
0
160
Keeping Ruby Running on Cygwin
fd0
0
160
AndroidアプリとCopilot Studioの統合
nakasho
0
100
#jawsugyokohama 100 LT11, "My AWS Journey 2011-2026 - kwntravel"
shinichirokawano
0
350
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.1k
データを"持てない"環境でのアノテーション基盤設計
sansantech
PRO
1
120
20260423_執筆の工夫と裏側 技術書の企画から刊行まで / From the planning to the publication of technical book
nash_efp
3
400
Digitization部 紹介資料
sansan33
PRO
1
7.3k
こんなアーキテクチャ図はいやだ / Anti-pattern in AWS Architecture Diagrams
naospon
1
450
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
2.4k
Featured
See All Featured
Bash Introduction
62gerente
615
210k
The Spectacular Lies of Maps
axbom
PRO
1
700
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
190
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
370
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
HDC tutorial
michielstock
2
630
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
130
Statistics for Hackers
jakevdp
799
230k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Thoughts on Productivity
jonyablonski
76
5.1k
Transcript
Snake Snacks FUNCTION COMPOSITION, THE DUMB WAY
WHAT WE WANT def inc(n): return n + 1 def
double(n): return n * 2 # in the REPL >>> (inc >> double)(2) 6 >>> (double >> inc)(2) 5
HOW ARE WE GONNA GET THERE? The Worst Way Possible™
DOUBLE UNDERSCORE METHODS
DOUBLE UNDERSCORE METHODS
DUNDER METHODS
DUNDER MIFFLIN
DUNDER METHODS, THE NICE WAY class Boss(object): def __init__(self, name):
self.name = name def __str__(self): return self.name def __repr__(self): return '<%s: %s>' % (self.__class__.__name__, self) def introduce(self): return "Please meet my boss, %s" % self
DUNDER METHODS, THE NICE WAY >>> b = Boss("Michael Scott")
>>> b <Boss: Michael Scott> >>> str(b) 'Michael Scott' >>> b.introduce() 'Please meet my boss, Michael Scott'
! DECORATORS "
DECORATORS, THE NICE WAY def memoize(fn): cache = {} def
inner(*args, **kwargs): key = str((args, kwargs)) if key not in cache: cache[key] = fn(*args, **kwargs) return cache[key] return inner
DECORATORS, THE NICE WAY @memoize def hype(stuff): return "OH YEAH,
IT'S %s" % stuff.upper() # is the same as... hype = memoize(lambda stuff: "OH YEAH, IT'S %s" % stuff.upper())
DECORATORS, THE NICE WAY >>> hype("cheese") "OH YEAH, IT'S CHEESE"
>>> hype("a moose") "OH YEAH, IT'S A MOOSE"
BUT… OBJECTS! class memoize(object): def __init__(self, fn): self.cache = {}
self.fn = fn def __call__(self, *args, **kwargs): key = str((args, kwargs)) if key not in self.cache: self.cache[key] = self.fn(*args, **kwargs) return self.cache[key]
BUT… OBJECTS! >>> hype("cheese") "OH YEAH, IT'S CHEESE" >>> hype("a
moose") "OH YEAH, IT'S A MOOSE" >>> hype.cache {"(('a moose',), {})": "OH YEAH, IT'S A MOOSE", "(('cheese',), {})": "OH YEAH, IT'S CHEESE"}
__gt__ class ChessPlayer(object): def __init__(self, name, elo): self.name = name
self.elo = elo def __gt__(self, other): return self.elo > other.elo
__gt__ >>> carlsen = ChessPlayer("Carlsen, Magnus", 2827) >>> almasi =
ChessPlayer("Almasi, Zoltan", 2707) >>> carlsen > almasi True >>> carlsen < almasi False
OUR FIRST TRY! class composable(object): def __init__(self, fn): self.fn =
fn def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) def __gt__(self, other): return self.__class__( lambda *args, **kwargs: other(self.fn(*args, **kwargs)) )
OUR FIRST TRY! @composable def inc(n): return n + 1
@composable def double(n): return n * 2 @composable def triple(n): return n * 3
OUR FIRST TRY! >>> (inc > inc)(0) 2 >>> (inc
> inc > inc)(0) 2
OUR FIRST TRY! ! 1 > 2 > 3 #
is equivalent to 1 > 2 and 2 > 3 # NOT (1 > 2) > 3
__rshift__ TO THE RESCUE! class composable(object): def __init__(self, fn): self.fn
= fn def __call__(self, *args, **kwargs): return self.fn(*args, **kwargs) def __rshift__(self, other): return self.__class__( lambda *args, **kwargs: other(self.fn(*args, **kwargs)) )
__rshift__ TO THE RESCUE! >>> (inc >> inc)(0) 2 >>>
(inc >> inc >> inc)(0) 3
__rshift__ TO THE RESCUE! >>> (inc >> double)(2) 6 >>>
(double >> inc)(2) 5 >>> (inc >> double >> triple)(2) 18
THANK YOU I'M SORRY