I haven't looked at Ruby for a long time. I've moved away due to the lack of typing. Any degree of typing would be helpful. Does it support typing yet?

_low_type_ is early days still, but I think this approach is clearly the future of ruby typing. If this gets baked into the language for full “compile” time support and minimal performance impact, it will be amazing: https://github.com/low-rb/low_type

Previously, RBS-inline was the closest answer to typed Ruby, it was the JSDoc of Ruby. Recently, when I stumbled upon low_type and tried it out in irb, it finally felt like ”this is it, this is the TS of Ruby” and with runtime validation.

I like it, it deserves attention, especially for those who are seeking for typed Ruby. With this, you can finally experience it, and the syntax feels more ergonomic than with Sorbet.

It is definitely better than RBS and Sorbet. But unless Github / 37Signals or Shopify decide to use it, it is highly unlikely Ruby Core will consider it.

Out of all three I think Shopify have the highest possibilities. There may be additional usefulness interms of ZJIT.

This is so goergeous compared to the mess that's out there now.

In my honest opinion, if you can't live without static typing, Ruby just isn't for you.

Adding static typing to a dynamic language mostly gives you the disadvantages of both, without a lot of benefits. It's better to stick to languages that were designed with static types from the start.

I love programming in Ruby, having to worry about type annotations and the additional constraints that come with them would take a lot of the fun out of that.

> Adding static typing to a dynamic language mostly gives you the disadvantages of both, without a lot of benefits.

As an engineer at a firm doing heavy duty data pipelines and internal tooling in a Sorbet-ified codebase, I disagree pretty strongly. While Sorbet type signatures are never going to win a syntax beauty contest, they are more than worth their weight in the way I can rely on them to catch typing and nilability goofs, and often serve as helpful documentation. Meanwhile, the internal code of most functions I write still looks like straight Ruby, fluent and uncluttered.

A good CI story that leans on tapioca was crucial here for us.

> Adding static typing to a dynamic language mostly gives you the disadvantages of both, without a lot of benefits.

Can you elaborate? I don't share this experience, and I'm interested in bringing static typing to a language without static typing, so I'd like to understand. In new Python and JavaScript codebases, optional typing has had clear benefits for refactoring and correctness and low costs for me. Legacy codebases can be different.

I don't have a great code example at hand unfortunately, but I found that people often tend to write more "nominally" typed code (expecting explicitly named classes) rather than taking advantage of duck typing (interfaces, structural types), meaning the code becomes more rigid, harder to change and more time wasted on resolving all the type checks, even if the code otherwise is perfectly reasonable and free of bugs.

In other words, I found that the resulting code often looked more like Java but with weaker guarantees about types and much worse performance.

Part of it is because Ruby imo, have a very nice syntax. With type annotation, it's becoming "ugly", a lot more verbose. It's no longer English-like. I do agree type have some advantages, but we need to get the DX right.

I've been using Ruby for more than 10 years now, and I only started using LSP recently. To me it's a nice addition but I can live without it. Type is just one of the tools, not the only one imo. Not trying to sound negative but type is becoming more like a hammer analogy nowadays.

And it's not limited to Ruby. Javascript, Python, all similar languages. Not everyone is a fan of type. We won't reach consensus imo and that's ok.

> With type annotation, it's becoming "ugly", a lot more verbose. It's no longer English-like.

In our codebase that uses Sorbet I find this is really only true at function boundaries. Within a function it is pretty rare that anything needs to be spelled out with inline annotations to satisfy the compiler.

This is my biggest irk about Sorbet: because its signatures are wordy and because it can't infer the generic type of a private method, it slightly pushes you towards NOT extracting helper methods if they are going to be 2-5 lines. With Sorbet annotation, it'd easily become 10 lines. So it pushes towards bigger methods, and those are not always readable.

If only private methods would be allowed not having typing at all (with a promise of not being used in subclasses, for example), and Sorbet would be used mostly on the public surface of classes, it'd be much more tolerable for me.

I mostly agree with you, but I'd say adding typing to low level core APIs is helpful in adding optimization opportunities.

I felt this way as well until very recently. Because Ruby actually commits to the whole "everything is an object" bit in an exceptionally clean way, it does duck typing extremely well -- if you squint, the fact that an object's methods define its type sorta-kinda means that you're working with interfaces (in the Go sense of the term).

Of course RBS makes this more explicit/verbose (in a good way), and ruby-lsp helps bring it all together in the editor.

I feel like I'm missing nothing compared to Python with type hints and pyright. Of course neither compare to an actually typed language at runtime, but at least as far as developer experience, it's pretty alright. I'm relatively new to Ruby but I went from really hating it to being pretty much fine with it for these reasons.

There's an official format for defining types in separate files (RBS) and some tooling to type check them (matz doesn't like types next to the source code).

There's a pretty battle tested tool to define inline types as ruby syntax and type check both statically and at runtime[0].

It's still not a particularly nice situation imvho compared to typescript or python, but there's been some movement, and there's a newsletter that follows static typing developments [1] which may give you some insights.

0: https://sorbet.org/

1: https://newsletters.eremin.eu/posts

I’ve used Sorbet on a project for 2 years recently and it honestly was the final nail in the coffin for Ruby for me.

Really rough around the edges, lots of stubs have to be added because support for gems is lackluster but whatever Sorbet generates are hit or miss etc. So you end up writing a lot of hard to understand annotations and/or people get frustrated and try to skip them etc.

Overall a very bad DX, compared to even typed Python. Don’t even want to compare it to TS because then it becomes really unfair.

Sorbet is a third-party add-on, not a part of Ruby. It's like if CoffeeScript was your final nail in the coffin for JavaScript.

There is [RBS](https://sorbet.org/) (part of ruby 3) and [sorbet](https://sorbet.org/). To be honest, these aren't widely used as far as I am aware. I don't know if it is runtime overhead, ergonomics, lack of type checking interest in the ruby community or something else. Type enforcement isn't a big part of ruby, and doesn't seem to be gaining much momentum.

> lack of type checking interest in the ruby community

IMHO if we wanted to write types in our programming language we would not have chosen Ruby for our programming tasks. We would have chosen one of the zillion of other languages. There were a lot of them when Ruby got traction about 20 years ago and many other languages have been created after then. It's not surprising that one of the main proponent of typing in Ruby is Shopify, because their path away from Ruby is very costly.

In my case one of the reasons I invested in Ruby is precisely because I did not have to write types.

Does it make Ruby slower than Java, my main language in 2005? Yes.

Is it fast enough for my customers? Yes. Most of them decided to use Ruby, then hired me.

Do I have to write unit tests to check for types? I don't.

Occasional problems that static types would have prevented to happen? Once or twice per year. Overall that's a good tradeoff because pleasing the type checker for non trivial types can be a time consuming task and some errors happen at runtime anyway, when the real world hits with its data a carefully type checked code base or a carelessly dynamic typed one. Think of an API suddenly returning a bad JSON, maybe an HTML 500 page. Static or dynamic typing, both won't help with that.

I too feel the type safety concern people have with ruby is overblown. The number of actual wrong type related issues I encounter is hardly enough to justify the costs of strong typing. The biggest type issue is with `nil` values and `NoMethodError` on `nil`. Guard clause or safe nav operator is usually sufficient protection for that. That said, I usually don't find myself needing to write that much defensive code for those cases.

I’ve been leaning hard into Sorbet runtime types for DSPy.rb[0] and finding real value. T::Struct at API boundaries, typed props for config, runtime validation where data enters the system.

For generating (with LLMs) API clients and CLIs it’s especially useful—define the shape once, get validation at ingress/egress for free.

Maybe momentum is happening in new projects rather than retrofits? [0] https://oss.vicente.services/dspy.rb

I've come to think that adding halfway-typing to languages designed from the start to be dynamic is mostly not worth the bother. It may help a little bit sometimes, but there's always going to be holes. If you really want strong typing, it's better IMO to bite the bullet and move to a language designed for it. Let Ruby be Ruby, ditto Python, Javascript etc. Pick up some JVM, .NET, Rust, Go, etc if you really want strong types.

Unfortunately, the type support is still useless. I abandoned Ruby for the same reason, and it is still relatively slow and eats a lot of memory.

It's literally faster than Python but ok.

Is being faster than Python considered to be a notable feature?

Personally I don't care about speed for this category of language. I just bring it up because Python is one of the most used languages, is even slower, yet that's never held against it. Just seems like a lazy way to dismiss Ruby. Yeah, it's not as fast as C, Go, Rust or Java. Everyone knows and raw speed obviously isn't the point of a dynamic scripting language...

Python is one the most popular programming languages. Ruby fits into a similar category as Python (high level, interpreted scripting language, very dynamic, has a rich ecosystem with tons of existing code). Being faster than Python makes it more attractive to use, or port Python codebases to.

Nobody cares about Ruby outside of RoR

Python is one of the Lingua Franca of scientific, data, and most importantly, ai communities

Has much bigger community than Ruby

Has much, much better tooling story

Has much better gradual typing story

Isn’t THAT much slower than Ruby, there are far more attractive targets than Ruby if you care about performance

> Python is one of the Lingua Franca of scientific, data, and most importantly, ai communities

You mean it's the most used frontend for all the C and C++ libraries that are used for scientific computing, data and AI.

Semantics.

Literally all those libraries are usable with Ruby. Libtorch, BLAS, LAPACK, Tensorflow, etc...

And with Java, and with Go, and with Rust, and with pretty much any language offering some form of FFI. But they're used with Python, and good luck convincing your interviewer that it should be used with Ruby.

> convincing your interviewer

Some of us don't work for others and just program what we want.

I found scrooge.

Bah, humbug!

And has no ecosystem compared to Python.

Speed isn’t why people choose Python.

There's a Ruby gem for almost anything

MVT for testing mobile spyware? There are whole sectors of industry, such as cybersecurity, where Python shines and Ruby is nowhere to be seen.

In what other language is MVT offered other than Python? That seems like a good example of unique language specialization and not reflective of a Ruby gap relative to any other language. I also don't think that's something you'd bundle & reuse in another offering. In my opinion that's the primary value proposition of building within an ecosystem

We have been adding Sorbet typing to our Rails application and it is a positive enhancement.

It’s not like Ruby becomes Haskell. But it does provide a good deal of additional saftey, less testing, LSP integration is good, and it is gradual.

There is a performance hit but we found it to be quite small and not an issue.

But there are area of our application that use Grape and it is too meta for Sorbet so we don’t try and use it there.

Same here. T::Struct and T::Enums at API boundaries has been the sweet spot—typed request/response models, runtime validation at ingress/egress.

I’ve been using this pattern for API clients[0] and CLIs[1]: define the shape once with Sorbet, get automatic JSON Schema generation when you need it.

[0] https://github.com/vicentereig/exa-ruby [1] https://github.com/vicentereig/lf-cli

> It’s not like Ruby becomes Haskell.

Well, maybe next time.

There’s projects trying to implement it. But I’ve never seen a project using typed Ruby.

I think most people who cared just moved to typescript.

Stripe is using typed Ruby: they are authors of https://github.com/sorbet/sorbet

Also: lots of other big Ruby shops are on Sorbet, like Figma, One Medical, Gusto etc. We discussed this at the SF Ruby meetup after this talk https://www.rubyevents.org/talks/past-present-and-future-of-...

I have seen that. But on the smaller companies it’s been my experience that Typescript has universal uptake for the frontend while Sorbet and RBS are things to keep an eye on but not getting any interest in using yet.

another early days project but pretty well thought out in that space: https://github.com/yippee-fun/empirical/blob/main/literally_...

Ruby has always been typed.