5 ms·
I remember having mixed feelings about Sorbet when I first joined Stripe in late 2018, but by the time I left, I found it indispensable. Especially after the VS
by reichertjalex 5y ago
I remember having mixed feelings about Sorbet when I first joined Stripe in late 2018, but by the time I left, I found it indispensable. Especially after the VS Code extension was released internally... holy crap, that made such a huge difference (vs having CI fail 20 mins after pushing up a PR because you forgot to run the typechecker script ahead of time, ugh).
This article also made me laugh, because it reminded me of one of my small pet peeves about the Ruby codebase at Stripe: the fact that you would often find `merchant`, `account`, `invoice`, etc used as method parameters that represented the _ID_ of the resource rather than the resource itself. So Sorbet definitely helped with that, but it also could've been nice to just write `invoice_id` instead... :P
Makes me nostalgic though, good times!
- clintonb 5y agoI also joined Stripe in 2018, and thought Sorbet was a waste of time. I quickly changed my mind when I realized how many incidents it prevented. Now I want types for :allthethings!
- itslennysfault 5y agoThis is exactly how I felt when I was first forced to use TypeScript instead of JavaScript, but I can't even tell you the number of hours it has saved me. Now, years later, I can't stand using regular JavaScript, and would never recommend it for any project that will be beyond a toy.
- Existenceblinks 5y agoI use Elm but not Typescript. I also write plain javascript intensively. I've seen languages adding static type layer after the fact they are dynamic type. They never end well, lots of edge case here and there, it becomes a problem rather than helper. Static type lang needs to think from start how they will compose nicely, what's pure, what's effect etc. However, the ship has sailed, I don't actually want to debate on this, because web tech is becoming a cult. (the last phrase added for downvote bait, lets do that!)
- yunohn 5y ago> I don't actually want to debate on this, because web tech is becoming a cult Your critique of dynamic languages adding types and failing would be more understandable if you mentioned some examples or explained what Typescript got wrong.
- hardwaresofton 5y agoIs there anything you can think to say to convince the old you? I have a few friends who haven’t yet seen the typing light. I also think Stripe’s API (external) should not be moving ids and objects. Given some payload in which ‘account_id’ is always present and ‘account’ may be the object (using ‘expand’ IIRC?) or not makes a lot more sense to me.
- jez 5y agoMy experience has been that the people opposed to types won't be convinced to start liking them by anything you can tell them or have them read. In all of the cases where I've seen Sorbet be adopted, the process looked like this: 1. Ambitious team who wants types does work to get the initial version passing in CI. Importantly, it's only checking at `# typed: false`, which basically only checks for missing constants and syntax errors. 2. That initial version sits silently in the codebase over a period of days or weeks. If new errors are introduced, it pings the enthusiastic Sorbet adoption team; they figure out whether it caught a real bug or whether the tooling could be improved. It does not ping the unsuspecting user yet. 3. Repeat until the pings are only high-signal pings 4. Turn Sorbet on in enforcing mode in CI. It's still only checking at `# typed: false` everywhere, but now individual teams can start to put `# typed: true` or higher in the files they care about. 5. Double check that at this point it's easy to configure whatever editor(s) your team uses to have Sorbet in the editor. Sorbet exposes an LSP server behind the `--lsp` flag, and publishes a VS Code extension for people who want a one-click solution. 6. Now the important part: show them how good Sorbet is, don't tell them. Fire up Sorbet on your codebase, delete something, and watch as the error list populates instantly. Jump to definition on a constant. Try autocompleting something. In my experience trying to bring static types to Ruby users, seeing is really believing, and I've seen the same story play out in just about every case. One final note: be supportive. Advertise one place for people to ask questions and get quick responses. Admit that you will likely be overworked for a bit until it takes off. But in the long run as it spreads, other teammates will start to help out with the evangelism as the benefits spread outward.
- hardwaresofton 5y agoThanks for this thoroughly practical advice -- evangelizing types inside Stripe must have been quite the journey! Been following since Dmytro and Paul's talk @ strangeloop.
- brandonbloom 5y ago> the fact that you would often find `merchant`, `account`, `invoice`, etc used as method parameters that represented the _ID_ of the resource rather than the resource itself I've encountered a few Rails projects in the wild that do this. One solution is to make liberal use of the `to_param` method. This method converts objects to strings that are intended for use in URLs. Of particular note, it's the identity function for strings and numbers, but returns `.id.to_s` for ActiveRecord models. Using this within definitions makes your function polymorphic for whether it accepts a model or an id. If you do this widely, would probably be best to monkey-patch in your own `to_id` method.
- clintonb 5y agoPretty much every model/resource has a `token` field, so we just call `invoice.token`, which is always a string.
- zamalek 5y ago.Net CodeContracts were this for me, but that was never fast. C# is a statically-typed language, so what kind of types could you further add to it? As a trivial example, maybe you want to ensure that `invoice_id` consists of at least 20 characters. CodeContracts would then statically attempt to prove that assertion for you. They had meticulously annotated the entirety of the .Net stdlib, and those annotations were spot-on. This obviously helps with things like `null`. It completely changed the way I code. You have to think a little bit more about how you structure your code if you plan to hand it off to a theorem prover. I unlearned several bad habits (I unlearned even more with Rust).
- actually_a_dog 5y agoWhat bad habits did you unlearn?
- sandermvanvliet 5y agoCodeContracts were a horrible hammer that people abused to not have to create proper types for things like an invoice id. If you have a type system then you should leverage it, not bolt on something extra
- alexandre_m 5y ago> vs having CI fail 20 mins after pushing up a PR because you forgot to run the typechecker script ahead of time Have you considered using pre-commit?