Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Snake Snacks: Function Composition, The Dumb Way
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Brian Hicks
September 07, 2017
Technology
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Snake Snacks: Function Composition, The Dumb Way
Brian Hicks
September 07, 2017
More Decks by Brian Hicks
See All by Brian Hicks
Esperanto
brianhicks
0
180
Make Snacks: Yet Another JavaScript Build System
brianhicks
0
160
State of Elm 2017
brianhicks
1
600
µKanren: A Minimal Functional Core for Relational Programming
brianhicks
0
500
Terraform All The Things!
brianhicks
2
450
Kubernetes for the Mesos User
brianhicks
1
150
ch-ch-ch-ch-changes in Elm 0.17.0
brianhicks
2
1.9k
State of Elm 2016
brianhicks
3
620
Mesos + Consul = Developer Happiness (JUG)
brianhicks
1
160
Other Decks in Technology
See All in Technology
コンテナ運用におけるネットワーク・コンテナコストの削減方法/How to Reduce Network and Container Costs in Container Operations
masakiokuda
2
380
僕のハーネスを紹介します
watany
5
1.4k
DBについての基礎説明(MySQL編) - コロプラ 2026年度 新卒研修
colopl
0
160
野蛮なアジャイル [サイボウズ発!]組織の常識を覆した反骨のスクラム実践記 / Barbaric Agile - Enterprise Agile Study Group
ama_ch
0
120
初海外で注意すべきこと12選!!!安全快適なre:invent生活にするために
yuuuuuuu168
1
200
AI駆動開発におけるハーネスエンジニアリングの勘所
tsukuboshi
1
480
Classmethod Company Deck
satoshi7
1
810
Claude Code on Bedrock で統制をかける小ネタ集/claude-code-bedrock-governance-tips
emiki
1
160
アウトプット初心者、半年間のふりかえり
4o1sobblue
0
470
Browser Spec: Testing Hotwire with Ruby
takahashim
1
160
AWS DevOps Agentはどこまで任せられるか 〜機能の現在地と、機能拡張の実践〜
nyankotaro
0
110
「私が一番顧客に詳しい」を捨てる~ 全員が一次情報に精通する開発チームをつくり、PMが次のボトルネックへ染み出すまで
kaminashi
3
1.2k
Featured
See All Featured
Amusing Abliteration
ianozsvald
1
350
Bash Introduction
62gerente
615
220k
How to make the Groovebox
asonas
2
2.5k
Ruling the World: When Life Gets Gamed
codingconduct
0
410
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
870
Git: the NoSQL Database
bkeepers
PRO
433
67k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
760
How STYLIGHT went responsive
nonsquared
100
6.3k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.9k
GraphQLとの向き合い方2022年版
quramy
50
15k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
740
We Have a Design System, Now What?
morganepeng
55
8.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