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
0
110
Snake Snacks: Function Composition, The Dumb Way
Brian Hicks
September 07, 2017
Tweet
Share
More Decks by Brian Hicks
See All by Brian Hicks
Esperanto
brianhicks
0
120
Make Snacks: Yet Another JavaScript Build System
brianhicks
0
74
State of Elm 2017
brianhicks
1
500
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
400
Terraform All The Things!
brianhicks
2
360
Kubernetes for the Mesos User
brianhicks
1
93
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
510
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
120
Other Decks in Technology
See All in Technology
JAWS FESTA 2024「バスロケ」GPS×サーバーレスの開発と運用の舞台裏/jawsfesta2024-bus-gps-serverless
ma2shita
3
260
ウォンテッドリーのデータパイプラインを支える ETL のための analytics, rds-exporter / analytics, rds-exporter for ETL to support Wantedly's data pipeline
unblee
0
130
AIエージェント元年@日本生成AIユーザ会
shukob
1
230
OSS構成管理ツールCMDBuildを使ったAWSリソース管理の自動化
satorufunai
0
650
Potential EM 制度を始めた理由、そして2年後にやめた理由 - EMConf JP 2025
hoyo
2
2.8k
フォーイット_エンジニア向け会社紹介資料_Forit_Company_Profile.pdf
forit_tech
1
1.7k
【詳説】コンテンツ配信 システムの複数機能 基盤への拡張
hatena
0
270
IAMのマニアックな話2025
nrinetcom
PRO
6
1.2k
MIMEと文字コードの闇
hirachan
2
1.4k
役員・マネージャー・著者・エンジニアそれぞれの立場から見たAWS認定資格
nrinetcom
PRO
4
6.3k
ABWG2024採択者が語るエンジニアとしての自分自身の見つけ方〜発信して、つながって、世界を広げていく〜
maimyyym
1
180
生成AI “再”入門 2025年春@WIRED TUESDAY EDITOR'S LOUNGE
kajikent
0
130
Featured
See All Featured
Optimizing for Happiness
mojombo
376
70k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
990
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Navigating Team Friction
lara
183
15k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Building a Scalable Design System with Sketch
lauravandoore
461
33k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
Mobile First: as difficult as doing things right
swwweet
223
9.4k
Typedesign – Prime Four
hannesfritz
40
2.5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
It's Worth the Effort
3n
184
28k
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