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
100
State of Elm 2017
brianhicks
1
540
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
440
Terraform All The Things!
brianhicks
2
400
Kubernetes for the Mesos User
brianhicks
1
100
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
550
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
130
Other Decks in Technology
See All in Technology
ソフトウェア品質を支える テストとレビュー再考 / 吉澤 智美さん
findy_eventslides
1
930
コミュニティと共に変化する 私とFusicの8年間
ayasamind
0
430
ユーザーストーリー x AI / User Stories x AI
oomatomo
0
110
エンジニアに定年なし! AI時代にキャリアをReboot — 学び続けて未来を創る
junjikoide
0
160
[2025-11-06] ベイズ最適化の基礎とデザイン支援への応用(CVIMチュートリアル)
yuki_koyama
1
390
MCP サーバーの基礎から実践レベルの知識まで
azukiazusa1
27
14k
開発者から見たLLMの進化 202511
ny7760
1
160
ピープルウエア x スタートアップ
operando
3
3.8k
Snowflakeとdbtで加速する 「TVCMデータで価値を生む組織」への進化論 / Evolving TVCM Data Value in TELECY with Snowflake and dbt
carta_engineering
2
230
設計は最強のプロンプト - AI時代に武器にすべきスキルとは?-
kenichirokimura
1
320
決済システムの信頼性を支える技術と運用の実践
ykagano
0
350
Digitization部 紹介資料
sansan33
PRO
1
5.9k
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
The Language of Interfaces
destraynor
162
25k
Optimizing for Happiness
mojombo
379
70k
Writing Fast Ruby
sferik
630
62k
Designing for Performance
lara
610
69k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Typedesign – Prime Four
hannesfritz
42
2.9k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Context Engineering - Making Every Token Count
addyosmani
8
360
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
2.9k
Why Our Code Smells
bkeepers
PRO
340
57k
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