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
130
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
130
Make Snacks: Yet Another JavaScript Build System
brianhicks
0
98
State of Elm 2017
brianhicks
1
530
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
430
Terraform All The Things!
brianhicks
2
390
Kubernetes for the Mesos User
brianhicks
1
99
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
540
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
130
Other Decks in Technology
See All in Technology
AWSで推進するデータマネジメント
kawanago
0
800
大「個人開発サービス」時代に僕たちはどう生きるか
sotarok
5
1.1k
実践アプリケーション設計 ①データモデルとドメインモデル
recruitengineers
PRO
5
1.4k
ガチな登山用デバイスからこんにちは
halka
1
200
Function Body Macros で、SwiftUI の View に Accessibility Identifier を自動付与する/Function Body Macros: Autogenerate accessibility identifiers for SwiftUI Views
miichan
2
150
事業価値と Engineering
recruitengineers
PRO
8
5.4k
ヒューリスティック評価を用いたゲームQA実践事例
gree_tech
PRO
0
420
250905 大吉祥寺.pm 2025 前夜祭 「プログラミングに出会って20年、『今』が1番楽しい」
msykd
PRO
1
210
kubellが考える戦略と実行を繋ぐ活用ファーストのデータ分析基盤
kubell_hr
0
120
Figma + Storybook + PlaywrightのMCPを使ったフロントエンド開発
yug1224
10
3.6k
2025年になってもまだMySQLが好き
yoku0825
6
2.5k
役割は変わっても、変わらないもの 〜スクラムマスターからEMへの転身で学んだ信頼構築の本質〜 / How to build trust
shinop
0
150
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Building Applications with DynamoDB
mza
96
6.6k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
KATA
mclloyd
32
14k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Gamification - CAS2011
davidbonilla
81
5.4k
Making Projects Easy
brettharned
117
6.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Become a Pro
speakerdeck
PRO
29
5.5k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
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