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
120
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
94
State of Elm 2017
brianhicks
1
520
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
430
Terraform All The Things!
brianhicks
2
380
Kubernetes for the Mesos User
brianhicks
1
97
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.8k
State of Elm 2016
brianhicks
3
530
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
130
Other Decks in Technology
See All in Technology
[SRE NEXT 2025] すみずみまで暖かく照らすあなたの太陽でありたい
carnappopper
2
520
Transformerを用いたアイテム間の 相互影響を考慮したレコメンドリスト生成
recruitengineers
PRO
2
500
低レイヤソフトウェア技術者が YouTuberとして食っていこうとした話
sat
PRO
6
5.1k
公開初日に Gemini CLI を試した話や FFmpeg と組み合わせてみた話など / Gemini CLI 初学者勉強会(#AI道場)
you
PRO
0
1.4k
【あのMCPって、どんな処理してるの?】 AWS CDKでの開発で便利なAWS MCP Servers特集
yoshimi0227
6
1k
AIエージェントが書くのなら直接CloudFormationを書かせればいいじゃないですか何故AWS CDKを使う必要があるのさ
watany
19
7.7k
20250708オープンエンドな探索と知識発見
sakana_ai
PRO
4
1.1k
MCP とマネージド PaaS で実現する大規模 AI アプリケーションの高速開発
nahokoxxx
1
490
今だから言えるセキュリティLT_Wordpress5.7.2未満を一斉アップデートせよ
cuebic9bic
2
170
サービスを止めるな! DDoS攻撃へのスマートな備えと最前線の事例
coconala_engineer
1
190
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.2k
組織内、組織間の資産保護に必要なアイデンティティ基盤と関連技術の最新動向
fujie
0
340
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Site-Speed That Sticks
csswizardry
10
700
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
29
9.6k
Visualization
eitanlees
146
16k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
A Modern Web Designer's Workflow
chriscoyier
695
190k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
How to train your dragon (web standard)
notwaldorf
96
6.1k
Bash Introduction
62gerente
613
210k
Optimizing for Happiness
mojombo
379
70k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.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