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
150
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
140
Make Snacks: Yet Another JavaScript Build System
brianhicks
0
120
State of Elm 2017
brianhicks
1
550
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
460
Terraform All The Things!
brianhicks
2
410
Kubernetes for the Mesos User
brianhicks
1
110
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
570
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
140
Other Decks in Technology
See All in Technology
予期せぬコストの急増を障害のように扱う――「コスト版ポストモーテム」の導入とその後の改善
muziyoshiz
1
1.4k
しろおびセキュリティへ ようこそ
log0417
0
290
Bill One急成長の舞台裏 開発組織が直面した失敗と教訓
sansantech
PRO
1
180
15 years with Rails and DDD (AI Edition)
andrzejkrzywda
0
160
0205_Claude_CodeでSEOを最適化する_AI_Ops_Community_Vol.2__マーケティングx_AIはここまで進化した__.pdf
riku_423
0
150
AIと新時代を切り拓く。これからのSREとメルカリIBISの挑戦
0gm
0
660
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
41k
Tebiki Engineering Team Deck
tebiki
0
24k
Deno・Bunの標準機能やElysiaJSを使ったWebSocketサーバー実装 / ラーメン屋を貸し切ってLT会! IoTLT 2026新年会
you
PRO
0
260
仕様書駆動AI開発の実践: Issue→Skill→PRテンプレで 再現性を作る
knishioka
2
550
CDKで始めるTypeScript開発のススメ
tsukuboshi
1
290
Mosaic AI Gatewayでコーディングエージェントを配るための運用Tips / JEDAI 2026 新春 Meetup! AIコーディング特集
genda
0
150
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
89
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
110
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
280
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
440
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
0
1.8k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
62
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.9k
WENDY [Excerpt]
tessaabrams
9
36k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
21k
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