Your presenter:
Getty @aisamanra Ritter The team: James @jamesiry Iry Dmitry @darkdimius Petrashko Paul @ptarjan Tarjan John @jvilk Vilk Jake @jez Zimmerman Trevor @moltarx Elliott Neil @neilparikh Parikh Russell @_russelldavis Davis Nelson @nelhage Elhage |
![]() |
Stripe is a software platform for running a business online.
More than 2,000 employees
Engineers in San Francisco, Seattle, Dublin, Singapore, and more...
We're hiring! (interns and full time)
"Break down obstacles to getting things done"
Let our engineers focus on product
Ruby is our primary programming language
Hundreds of engineers
Millions of lines of code (monorepo)
Thousands of changes to the monorepo per day
Responses from biannual eng-wide survey:
Too long to get feedback
Too long to grasp unfamiliar code
Too easy to accidentally break things
Do nothing: Opportunity cost (productivity, breakages)
Treat the symptoms of existing code: New symptoms pop up
Rewrite everything: 100s of engineers, all-or-nothing
Rewrite some things: 10s(?) of engineers, partial impact
Type checker: 3 engineers, incremental value in months
Do nothing: Opportunity cost (productivity, breakages)
Treat the symptoms of existing code: New symptoms pop up
Rewrite everything: 100s of engineers, all-or-nothing
Rewrite some things: 10s(?) of engineers, partial impact
Type checker: 3 engineers, incremental value in months
Oct 2017 – Kickoff
Feb 2018 – First typed code
June 2018 – Enforced in CI for every Stripe engineer
... lots of other stuff ...
Jun 2019 – Open source!
Too long to grasp unfamiliar code
Too long to get feedback
Too easy to accidentally break things
def self.find_card_similarity(merchant:)
similarity_data = SimilarityDB.fetch(merchant)
similarity_data ||= []
process_similarity_data(similarity_data, merchant)
end
Hundreds of engineers means ~all code is unfamiliar
def self.find_card_similarity(merchant:)
# Is `merchant` a string ID, or a Models::Merchant instance?
similarity_data = SimilarityDB.fetch(merchant)
similarity_data ||= []
process_similarity_data(similarity_data, merchant)
end
Hundreds of engineers means ~all code is unfamiliar
def self.find_card_similarity(merchant:)
# Is `merchant` a string ID, or a Models::Merchant instance?
similarity_data = SimilarityDB.fetch(merchant)
# Is `similarity_data` ever actually falsy? Why?
similarity_data ||= []
process_similarity_data(similarity_data, merchant)
end
Hundreds of engineers means ~all code is unfamiliar
Already have massively parallel distributed CI test runner
def self.find_card_similarity(merchant:)
# Is `merchant` a string ID, or a Models::Merchant instance?
similarity_data = SimilarityDB.fetch(merchant)
# Is `similarity_data` ever actually falsy? Why?
similarity_data ||= []
process_similarity_data(similarity_data, merchant)
end
"I want to change this code!"
... is it enough if the tests pass?
... is it enough if the QA / canary deploys have no errors?
Ruby 3 stdlib will ship with type definitions.
We're collaborating closely with the Ruby core team
See more details in talks by Matz, Yusuke Endoh and us @ RubyKaigi 2019
1,100 pull requests commits since open source
152 total contributors
117 pull requests: types for Ruby stdlib
203 pull requests: types for gems
34 external contributors to sorbet-typed
Make it even faster
Implement most-needed language features
Invest heavily in editor tools (open source soon!)