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
My Problem, My Solution
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Penelope Phippen
September 12, 2014
Technology
67
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
My Problem, My Solution
A talk about typing I gave at Frozen Rails 2014
Penelope Phippen
September 12, 2014
More Decks by Penelope Phippen
See All by Penelope Phippen
Introducing Rubyfmt
penelope_zone
0
620
How RSpec Works
penelope_zone
0
6.8k
Quick and easy browser testing using RSpec and Rails 5.1
penelope_zone
1
110
Teaching RSpec to play nice with Rails
penelope_zone
2
180
Little machines that eat strings
penelope_zone
1
130
What is processor (brighton ruby edition)
penelope_zone
0
150
What is processor?
penelope_zone
1
390
extremely defensive coding - rubyconf edition
penelope_zone
0
300
Agile, etc.
penelope_zone
2
260
Other Decks in Technology
See All in Technology
実装だけじゃない! CCA-F取得エンジニアが教えるClaude Code開発プロセス活用術
diggymo
2
550
最適な自走を最小限の支援で — M&Aで拡大する組織で少人数SREが挑んだ1年 / SRE NEXT 2026
genda
0
1.1k
DatabricksにおけるMCPソリューション
taka_aki
1
230
AIと共生する開発者プラットフォーム:バクラクのモノレポ×マイクロサービス基盤
sakajunquality
2
3.4k
環境凍結という Toil を倒す -セルフサービス型 Ephemeral テスト環境の 設計と実践
shirouz
1
2.3k
なぜ私たちのSREプラクティスはなかなか機能しないのか 〜システムより先に組織を見る〜 / Why our SRE practices aren't really working
vtryo
3
3.6k
ゴールデンパスは敷いただけでは道にならない ─ 企画部門のエンジニアが技術標準を事業価値に変えるまで
mhrtech
0
130
世界、断片、モデル。そして理解
ardbeg1958
1
100
Foxgloveについて 実際にExtensionを開発して公開するまでの話 / About Foxglove: The Story of Developing and Releasing an Extension
ry0_ka
0
200
人を動かすのは時間ではなく、納得感 〜新任EMが入社3ヶ月、組織を2回変えた話〜
kakehashi
PRO
3
210
SRE依存からの脱却 運用を開 発チームへ移す、 フルサイ クル開 発体制の実践
joooee0000
0
2.6k
「ちゃんとやっている」は独りよがりだった ― 不安に寄り添うインシデント対応へ / Towards incident response that addresses anxieties
chmikata
1
4.9k
Featured
See All Featured
sira's awesome portfolio website redesign presentation
elsirapls
0
300
Scaling GitHub
holman
464
140k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Code Review Best Practice
trishagee
74
20k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
220
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
460
Java REST API Framework Comparison - PWX 2021
mraible
34
9.5k
The Cult of Friendly URLs
andyhume
79
6.9k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
170
Making Projects Easy
brettharned
120
6.7k
Transcript
The maybe monad as a replacement for nil
My Problem My Solution
Everyone Stand Up
None
a!/samphippen
My Problem
Type Checking is the Antithesis of Object Oriented Programming
Type
Types
What is a type?
What is a data type?
A type is a set of possible values and operations
Class
Terms are literally interchangeable in Ruby
Terms are literally interchangeable in Ruby Konstantin
Fixnum
✕
+
/
—
1.class # => Fixnum
You know what all these things do
1+1 # => 2
Array
count
each
In Ruby some types are interchangeable
Typeclass
A set of types and common operations
There is some expectation of what the operations will do
Duck typing
All number types in Ruby form a typeclass
Fixnum Float BigDecimal
Numeric Op Numeric = Numeric
Positive Numeric + Positive Numeric = Positive Numeric =
Also collections
Hash Set Array
Type Checking is the Antithesis of Object Oriented Programming
Type Checking is the Antithesis of Object Oriented Programming
Type Checking
This term has two meanings
Compile time type checking
public static final List<string> seriouslyiamsoboredwh ocares
Like in Java
Clearly we don’t do this in Ruby
So what do I mean?
ActiveRecord::Base #find_by
pony = Pony.find_by(:id => smth) pony.neigh
pony = Pony.find_by(:id => smth) if pony pony.neigh else puts
“No Pony can’t neigh” end
The problem here is two return types
nil Pony < AR::Base
We’re forced to add a type check
Also, I think this is the wrong type check
pony = Pony.find_by(:id => smth) if !pony.nil? pony.neigh else puts
“No Pony can’t neigh” end
A more explicit type check
But still wrong
pony = Pony.find_by(:id => smth) if !pony.nil? pony.neigh else puts
“No Pony can’t neigh” end
pony = Pony.find_by(:id => smth) if pony.respond_to?(:neigh) pony.neigh else puts
“No Pony can’t neigh” end
This type checking adds unnecessary complexity to our app
Type Checking is the Antithesis of Object Oriented Programming
Type Checking is the Antithesis of Object Oriented Programming
Antithesis
I am using it to mean “DOING IT WRONG”
Type Checking is the Antithesis of Object Oriented Programming
Type Checking is the Antithesis of Object Oriented Programming
Object oriented programming
Konstantin Haase says:
Data abstraction and control abstraction
Alan Kay says:
Everything is an object
Objects communicate by sending and receiving messages
def bees if :bar == a.foo else end end
def bees a.foo nil end
Tell don’t ask
Objects have their own memory (in terms of objects).
Data hiding
Every object is an instance of a class (which must
be an object).
The class holds the shared behavior for its instances (in
the form of objects in a program list)
To eval a program list, control is passed to the
first object and the remainder is treated as its message.
Type Checking is the Antithesis of Object Oriented Programming
Type Checking is the Antithesis of Object Oriented Programming
My Problem
My Problem
My Solution
Just always make your methods return things of a consistent
type class
Thanks!
No obviously there’s more
Third party APIs do this all the time
pony = Pony.find_by(:id => smth) if pony pony.neigh else puts
“No Pony can’t neigh” end
The problem here is two return types
As a client of this API I am forced to
add a type check
nil is such a common case
How do we fix it?
Null object pattern
I think this one is quite well known
class Pony def horse_power 0.5 end end
Pony.find_by( :key => value ) || NullPony.new
class NullPony def horse_power 0 end end
NullPony quacks the same as Pony
Solves the typing problem
Summing over ponies will only count Pony objects
0 might be the wrong default
Pony * NullPony = 0
Decided the default for horse_power when defining the class
Change is inevitable
Can’t predict how NullPony will be used in the future
Maybe Typeclass
Solves same problem
Allows for runtime defaults
#map(&blk) -> Maybe #value_or(a) -> a
class Just def initialize(value) @value = value end def map(&blk)
def value_or(x) Just.new(blk.call(@value)) @value end end end
class Nothing def map(&blk) self end def value_or(x) x end
end
A consistent interface for dealing with missing values
NoMethodError: undefined method `foo' for nil:NilClass
NoMethodError: undefined method `foo' for nil:NilClass
[Maybe, Nothing, Maybe]
call map on all of them
collapse with value_or
To Recap:
Null object can replace nils if you know the defaults
at class definition time
Maybe if you want defaults at run time
Your job is not to make Alan Kay happy
RSpec RSpec ! ! RSpec 3
tinyurl.com/ samfr2014
Let’s have some questions a!/samphippen
[email protected]