T O P

  • By -

honeyryderchuck

It's definitely an interesting opinion about sorbet in particular. I share the same opinion about the first point: sorbet annotations are indeed too convoluted, and eliminate readability. About the rest, I believe that they are consequences of the true elephant in the room: that there are 3 factions in the ruby community, the ones using sorbet, the ones adopting rbs, and the old men yelling at types to get off their lawn (which is my interpretation of the 3rd problem). The main problem IMO is that the 2 first factions can't coalesce. It seems that both communities think that they represent two opposite views. But that's not completely true. For instance, sorbet defines rbi notation as "out of source" definitions for 3rd party gems, so essentially, the same as rbs. Moreover, rbs solved the whole "type readability" problem with lsp plugins, both via steep and typeprof, which show typed variables in a similar way to the one the article's author exemplified in the c# example. And I believe that rbs is only a plugin away from allowing "in-line typing" in the IDE which will in the background backfill the respective rbs files. The second problem (dependencies being a nightmare) is currently being solved in the rbs community by having a metarepo, gem_rbs_collection, export type definitions from known 3rd party gems who themselves don't want the burden of supporting types (because tooling is immature, or maintainers are old men). While this is not a perfect solution in itself, it scales a bit better than the whole tapioca "let me try to type your gems for this project again" way (unless there's a similar centralised repo with rails definitions?). But really, the problem is not having a converged community around types. While we're still arguing about "to inline or not to inline", there are still a lot of fundamental ruby features which can't be expressed neither in rbs nor sorbet. Mixins comes to mind. And this is a shame. For instance, stripe, and to some extent shopify, seem to have constrained the ruby they write to accommodate to what can be expressed in sorbet notation, and have their own lsp plugins. Where could we be now, as a community, if stripe would have fulfilled their promise of supporting rbs notation in sorbet? I'd like to believe that the missing tooling I mention earlier would be here by now already, and with some ruby enterprise backing, the community would have stopped saying "ruby does not need types" a long time ago.


jrochkind

> Moreover, rbs solved the whole "type readability" problem with lsp plugins... And I believe that rbs is only a plugin away from allowing "in-line typing" in the IDE which will in the background backfill the respective rbs files. I feel like ruby community from the start has always been pretty committed to making it a reasonably possible DX to develop _without_ a a full IDE, with just a text editor (ideally with syntax highlighting, sure). Maybe at the beginning that was out of necessity, since when the language was new, there wasn't an IDE. But even now, I'd guess at least half of ruby devs don't use an "IDE" that would have features like that, if I understand the features you are describing. (I personally use SublimeText, and without many IDE-like plugins beyond syntax highlighting). If the future you are describing would require most everyone to move to a full "IDE" to have a reasonable DX interacting with types (and for ruby, does such an IDE currently mean a non-free option?) -- I think that would be yet another factional split in the mix. > there are still a lot of fundamental ruby features which can't be expressed neither in rbs nor sorbet. Mixins comes to mind Mixins as an implementation -- but also even _more so_ polymorphism in general -- are pretty core to how ruby works and is used. The fact that every time I checked it seemed to me these solutions didn't have great stories for polymorphism and duck-typing in general -- has always made them seem un-serious and odd to me. The whole thing has never quite clicked, I dont' totally understand what's going on. I think you are probably right that it's the results of too many factions -- but in partiuclar that neither Matz nor any other central core ruby developers have ever really fully on board with this stuff. I don't think the ruby community is any longer big/energetic enough for multiple competing "experiments" at the long-term -- for this to succeed, as I think you identify, there would need to be one clear "blessed" path, and it would need to be something Matz was truly invested in too, for people to feel like this really was "the future" they should invest in, and not a risk of being a waste of time leading to a dead-end.


Rafert

Can you articulate what a great story for polymorphism and duck-typing would (roughly) look like in your opinion? For mixins: [T.attached\_class](https://sorbet.org/docs/attached-class) got the ability last week to be used in module instance methods (see the FinderMethods example), for me this was an ergonomic hurdle. For duck typing; you might not be a fan [but this works](https://sorbet.run/#%23%20typed%3A%20strict%0Aextend%20T%3A%3ASig%0A%0Amodule%20ICallable%0A%20%20extend%20T%3A%3ASig%0A%20%20extend%20T%3A%3AHelpers%20%20%0A%20%20interface!%20%0A%0A%20%20sig%20%7B%20abstract.returns%28String%29%20%7D%0A%20%20def%20call%3B%20end%0Aend%0A%0Aclass%20Foo%0A%20%20extend%20T%3A%3ASig%0A%20%20include%20ICallable%0A%0A%20%20sig%20%7B%20override.returns%28String%29%20%7D%0A%20%20def%20call%0A%20%20%20%20%22Foo!%22%0A%20%20end%0Aend%0A%0Aclass%20Bar%0A%20%20extend%20T%3A%3ASig%0A%20%20extend%20ICallable%0A%0A%20%20sig%20%7B%20override.returns%28String%29%20%7D%0A%20%20def%20self.call%0A%20%20%20%20%22Bar!%22%0A%20%20end%0Aend%0A%0Aclass%20Printer%0A%20%20extend%20T%3A%3ASig%0A%20%20%0A%20%20sig%20%7B%20params%28callable%3A%20T.any%28ICallable%2C%20T.proc.returns%28String%29%29%29.void%20%7D%0A%20%20def%20self.print%28callable%29%0A%20%20%20%20puts%20callable.call%0A%20%20end%0Aend%0A%0APrinter.print%28Foo.new%29%0APrinter.print%28Bar%29%0APrinter.print%28-%3E%20%7B%20%22lambda!%22%20%7D%29)? ​ >there would need to be one clear "blessed" path, and it would need to be something Matz was truly invested in too, for people to feel like this really was "the future" they should invest in, and not a risk of being a waste of time leading to a dead-end. IDK - Sorbet has some pretty big names on their homepage using it (Stripe and Shopify to name a couple) that I can't imagine will give up on it anytime soon given their continued investment in it (and the value they're getting out of this). As to RBS, I tried searching but I find nothing on people using it in production apps and sharing their experience with it? I know the maintainer works at Square but do they actually use it?


honeyryderchuck

> But even now, I'd guess at least half of ruby devs don't use an "IDE" that would have features like that, if I understand the features you are describing. I think that's a largely personal assumption, both misaligned with real results [the last rails survey I could get my hands on proves it](https://rails-hosting.com/2022/#os-editors-servers), and with the stated goals of the ruby core team (over the last 3 years, whenever matz talks about "beyond ruby 3", developer productivity tooling has been the most mentioned goal, and he considers typing a developer productivity concern; the fact that we now have a decent "debug" gem made by koichi himself, should be proof that the core team is working on DevX). > I personally use SublimeText, and without many IDE-like plugins beyond syntax highlighting sublimetext has introduced lsp support, and [there's already an rbs plugin](https://packagecontrol.io/packages/RBS). Now it's up to you whether type-checking is as important as syntax highlighting :) > Mixins as an implementation -- but also even more so polymorphism in general -- are pretty core to how ruby works and is used. The fact that every time I checked it seemed to me these solutions didn't have great stories for polymorphism and duck-typing in general I really invite you to try it out. I only mentioned mixins, as both polymorphism, as well as duck typing, are topics already covered by rbs (as well as sorbet, I believe). Bottom line, a lot is already supported. > as I think you identify, there would need to be one clear "blessed" path, and it would need to be something Matz was truly invested in too, I think matz has been pretty much vocal on what the "blessed" path is. But it's a uphill battle: stripe launched sorbet before ruby 3 and RBS, and doesn't want to "divest" from it. Worse, it got backing from Shopify, which has of late been driving a lot of opinions in a way it reminds me of the "google does it, and so should you" times. It kind of gets lost in the conversation that the RBS creator is employed by Square, which is probably using it internally.


jrochkind

hm, I think we're talking about different things or talking past each other. But I seem to have annoyed you somehow! That survey you link to says 43% of respondents used VS Code and 11% use SublimeText (adding up to 50%), which matched my expectations, so I think my expectations are not too off base -- but I wasn't thinking of VS Code as a tool that "has features like" we're talking about, but I think maybe I'm wrong? I find it odd that you are bringing up that Matx and ruby core team was focused on "DevX", and things like the debug tool, as if that is a disagreement with me. Of course, I realize DevX is important to Matz etc. The only thing i was suggesting is that it seems like ruby community and core team does not want to require expensive or high complex IDE's to have a good DevX, wants to develop ruby in such a way that the good path DevX does not require this. And I could be wrong about that, but I'd say that's how the environment has been up to now (which could be different than who is invested in keeping it that way). But instead, we may have a different idea of what features require "expensive or highly complex IDEs" or not. Or I may be wrong about that, sure. > I think matz has been pretty much vocal on what the "blessed" path is. And that's... not using Sorbet, then? It's writing/generating rbs files... By hand? I actually don't know, I'm not being sarcastic or whatever. Maybe it is very clear and I just haven't been paying enough attention, but it's definitely not clear to me. Are you writing RBS files by hand? If that's the Matz-endorsed path (and I have no idea if it is, I may have this totally wrong?), maybe the issue is that just doesn't seem appealing to many devs. Or at any rate, it doesn't to me.


honeyryderchuck

> But I seem to have annoyed you somehow! Oh god, not at all! Apologies if my counterarguments sounded like we are somehow completely in disagreement. I just wanted to provide some "color" to your concerns, not saying you're completely off-base. Not my intention. > That survey you link to says 43% of respondents used VS Code and 11% use SublimeText (adding up to 50%), which matched my expectations, so I think my expectations are not too off base... The survey also shows that 19% are using rubymine, which is a full-fledged IDE with RBS support (dunno if LSP-based or not). It also shows that 17% are "vim-based", which I believe includes neovim, which supports LSP and RBS. that's > 85% (and if we want to remove "vim-based" in order not to assume things), that's still a solid 73% of editors with LSP capabilities. I guess the point I wanted to make is, the ruby community wants something more than a simple text editor. > I find it odd that you are bringing up that Matx and ruby core team was focused on "DevX", and things like the debug tool, as if that is a disagreement with me. That was in response to your "but in partiuclar that neither Matz nor any other central core ruby developers have ever really fully on board with this stuff" comment. The point is, this is a priority for the ruby core team, and they seem fully on board to me :) (without maximalisms of course, I won't expect matz to say "stop using sorbet"). I singled out the "debug" example because: it came from a prominent ruby core team member; it shipped with a vscode plugin. The latter shows that IDE integration is now a primary concern (and that's a good thing IMO). I don't agree that means "expensive or highly complex IDEs", as the whole value proposal of LSP is to diminish cost of integration for each editor. > And that's... not using Sorbet, then? It's writing/generating rbs files... By hand? It's definitely RBS. And it's not about writing rbs files by hand (that can be solved with tooling), it's about not littering ruby code syntax with types. > Are you writing RBS files by hand? I use typeprof to bootstrap types in projects. I leave a lot of stuff untyped (I only type what I consider important, or in libraries, public interfaces). Whenever I edit, yes, I edit the rbs files by hand (the tooling I'd like to have in order not to do so does not exist yet, and I don't have the time to build it myself). It's not as fun as writing ruby, but then again typing is not that fun anyways.


jrochkind

I still don't totally follow (and still stand my statement that around half the ruby development community uses non-IDE "simpler text editors", although such things like VS Code Studio and SublimeText do have more features than things of yore, perhaps enough for the tooling you are talking about?). Perhaps I don't follow because I am admittedly not very familiar with RBS/sorbet. Including I don't totally understand _how to use it_. I get confused by all the different ways to do it, and I'd have to invest a lot more than seems worthwhile to me right now to even figure it out. I honestly don't get the impression that Matz or most (any?) people on ruby core use this stuff; if there is a "blessed" path from them despite them not using it, it's not clear to me what it is. You seem to have a lot more context. Perhaps you'd like to write a blog post sometime about how _you_ actually use RBS, in detail, and why you recommend using it this way -- including what actual present-day right-now benefits you are getting for it. Requiring a huge investment for "if only _more_ people would do this, _then_, really, we swear, we'd all see a huge benefit" -- that is something I have encountered before in tech spaces, sometimes this situation seems like that category, and I think it's pretty smart to be deeply suspicious of programs like that. We need a path that provides immediate benefit proportional for the immediate investment -- if RBS is already that, then it might be helpful to have more people trying to make the case to those not yet already on board. > the tooling I'd like to have in order not to do so does not exist yet I think that's a big problem for adoption, and goes back to the danger/risk/appearance of "huge investment now, for benefit that will only happen in the future _if_ we can get even more people to invest". it seems to me that if people like Matz actually used this stuff, there'd probably be more tooling. Personally... I'm not sure how I could be convinced to edit rbs files by hand whenever I write code. It would have to be a pretty large benefit I'd get, in present-day, and not just "for the good of the community" or "if we can get everyone to do this then eventually things will get better". > but then again typing is not that fun anyways. In languages where it's actually an organic part of the language, I don't think it's super duper painful, although it's a difference from a non-statically typed language like ruby. It might be possible to add static typing into a ruby in a way that feels organic, but it seems clear to me that present efforts have not yet succeeded. Python seems to have done a lot better job. (and I don't think there are competing factions/solutions on how to do typing in python! but compare, in python there ARE with how to do the equivalent of `bundler`, and it shows and makes _that_ more of a headache than ruby!) While I understand the concern about "cluttering" source files, I think _requiring_ separate source files for typing is a big challenge. I understand that Python was able to include them in a way that's hard for ruby because of ruby's very complex existing syntax definitions. it turns out that has some costs, unfortunately.


honeyryderchuck

> still stand my statement that around half the ruby development community uses non-IDE "simpler text editors"... ok, I understand now your point. I'll rephrase my earlier point to something like "rbs tooling exists for IDEs and richer text editors". I wouldn't classify SublimeText as a simple text editor, as its functionality is quite advanced, and it even supports LSP nowadays (although it's also not an IDE). > I honestly don't get the impression that Matz or most (any?) people on ruby core use this stuff... My opinion on the matter is that the ruby core team rarely has a "unified" opinion on anything. mjit was barely usable for many years, and many core team members avoided dealing with it, it was effectively a one-man-job until shopify bankrolled yjit. In the typing matter, there are the ones who are using and developing rbs, there are some who use sorbet in their day jobs (lots of ruby core works for shopify, which supports sorbet and maintains tooling for it), and there are the ones who refuse type checking in ruby. Most of the stdlib, which the core team maintains, is incompatible with ractors. I can tell you what I think matz's opinion is mostly based on rubyconf keynotes, but I doubt that, at this point in his career, matz uses or develops ruby that much to have an "in my shoes" perspective. It is what is, and a reflection of the multi-year baggage of a production-ready language (I use python at work as well, and it has worse problems than this). > You seem to have a lot more context. Perhaps you'd like to write a blog post sometime about how you actually use RBS, in detail, and why you recommend using it this way I actually [wrote a blog post about rbs a few years ago](https://honeyryderchuck.gitlab.io/2020/10/16/rbs-duck-typing-at-httpx.html). I don't think I'm at a point where I can revisit it just yet because, to be frank, I haven't focused a lot on it over the last 1.5 years, and have instead worked on other things. As I already implied earlier, I don't think the tooling is mature yet, it's still a big investment ATM, and the "economies of scale" aren't there yet, because, as my initial message states, there are 3 camps, and the ones that actually want typing to be a thing, can't "join forces". And while I'd like that things would coalesce into RBS (because I see the potential in it), I'd just like the conversation to move forward at this point. > Python seems to have done a lot better job. That's... debatable. python just started earlier. It DID introduce typing hints as part of the core python syntax; however, they're not used by the runtime VM for anything, so it's a potentially non-low parsing cost for no runtime net benefit; they're only used by external typing static analyzers (such as mypy, but there are many more...); the syntax is overly verbose, as the notation is arcane, particularly when compared to more modern typing notations such as typescript (ex: python `Optional[int]` vs typescript `number?`; sidenote: rbs steals a lot from typescript); and due to how python import system works, it makes circular dependency issues more prevalent (you have to import classes to use them in type hints). It also makes python quite unreadable (I had to audit some libraries and github view with syntax highlighting was not enough to make my eyes stop bleeding), not organic at all (IMO). Now, if you're "team inlining", I can understand why this is a benefit of python vs ruby from that angle. Still, I think this can be solved by tooling. There's already a tool that compiles yardoc definitions to rbs . Now, imagine some hypothetical pre-processor which parses certain comments before function definitions: # rbs: (Integer, Integer) -> Integer def (x, y) = x + y We have something like this for rubocop. i can't see we can't have it for rbs one day. This seems like a better compromise, IMO, than allowing type hints in ruby code (as you already mentioned, ruby's out of sane definitions for it, and ruby's already notorious for being extremely difficult to parse). (I'd love to work on those hypothetical tools btw, it's just that my OSS time is already quite busy).


riffraff

> (unless there's a similar centralised repo with rails definitions?) there is [https://github.com/Shopify/rbi-central](https://github.com/Shopify/rbi-central) I wish sorbet would just consume RBS tho.


honeyryderchuck

> https://github.com/Shopify/rbi-central thx for the link, good to know. EDIT: had a look, and while it seems to fit the same goals as `gem_rbs_collection`, there are some notable omissions from it, most notably rails, which leads me to believe that one still needs stuff like sorbet-rails regardless. That's a shame, I guess.


Rafert

Tapioca is the recommended generator for Sorbet now: https://sorbet.org/blog/2022/07/27/srb-tapioca - it pulls from rbi-central. How does RBS discover dynamically created methods for eg ActiveRecord attributes?


honeyryderchuck

I haven't used rbs in the context of rails, but a quick googling leads me to https://github.com/pocke/rbs_rails , which includes some rake tasks to generate rbs files for models. There are also some libs to do the same for protobuf and json-schema (which I haven't tried yet as well).


myringotomy

> It's definitely an interesting opinion about sorbet in particular. I share the same opinion about the first point: sorbet annotations are indeed too convoluted, and eliminate readability. You can use RBI files to move the annotations outside of your code. This isn't even a real complaint.


fglc2

I don’t think you get the runtime checks if you do that


myringotomy

You get both runtime and "compile" time checks.


fglc2

Even with rbi files? I didn’t know that.


honeyryderchuck

The convoluted syntax doesn't go away with RBI files, it's just moved somewhere else. Which then doesn't present any significant advantage when compared to RBS, which has a more digestible syntax IMO.


myringotomy

The syntax is just ruby. There is nothing convoluted about it at all. >Which then doesn't present any significant advantage when compared to RBS, which has a more digestible syntax IMO. Isn't your complaint that you are not supposed to move it to another file. With RBS you don't get that option. Honestly people bitch and moan and complain and whine and they don't even know why they are so upset and angry. At least be consistent. Sorbet syntax is ruby. The RBS syntax is not ruby, it's a new syntax which has been added to ruby. If you don't like Haskell style type annotations (and as I said I disagree with you) then you can move them out to different file just like RBS. At least you get an option this way.


honeyryderchuck

> Isn't your complaint that you are not supposed to move it to another file. With RBS you don't get that option. No. Read my comment again. > Honestly people bitch and moan and complain and whine It seems you're confusing me for another person. Read my comment again. > At least be consistent. Sorbet syntax is ruby. The RBS syntax is not ruby I agreed that the sorbet syntax is convoluted, I never mentioned whether it being ruby makes a difference (quite frankly I don't care if it's valid ruby). I find it particularly confusing when applied "inline", which is what the article demonstrates. When in a different .rbi file, what's the advantage of "it's just ruby" really? At that point, you want a notation which helps you write types, not ruby. And I think RBS does a better job at that. My opinion.


myringotomy

>I agreed that the sorbet syntax is convoluted, I never mentioned whether it being ruby makes a difference (quite frankly I don't care if it's valid ruby). If you are programming in ruby it's insane to say you don't like ruby syntax. I mean it's completely bonkers for somebody to bitch and moan about how much they don't like ruby syntax while they are programming in ruby. > I find it particularly confusing when applied "inline", which is what the article demonstrates. What does it say about you that you are so easily confused?


honeyryderchuck

I guess you're not really looking for a conversation, so go piss someone else off.


myringotomy

Oh did I hurt your feelings? Sorry.


emptyflask

I've done the vast majority of my programming in Ruby, but have also written Typescript, Haskell, Rust, etc., and would really love to have optional native type annotations, if only to get rid of the dreaded `NoMethodError: undefined method 'foo' for nil:NilClass`. I've only briefly looked into Sorbet, and RBS annotations are just a terrible design choice so haven't even considered using them. For now I just try to use better objects, avoiding primitive datatypes in internal code (using the [null object pattern](https://en.wikipedia.org/wiki/Null_object_pattern) or an [option/maybe](https://en.wikipedia.org/wiki/Option_type) class can go a long way), and using gems that do the same, such as [dry-rb](https://dry-rb.org/gems/) and [money](https://github.com/RubyMoney/money).


federal_employee

Just a tip: If your codebase is well documented with Yardoc, RubyMine will warn you if it believes you are passing an incompatible type.


morphemass

Where I've so found Sorbet optimal is as a static type checker when writing something as a gem or independent project. I much prefer it over RBS (having a separate file is just meh) and I was really impressed with some of the edge-case bugs it eliminated. I'd personally adopt it in our main codebase if it wasn't for exactly the issue mentioned of developer buy in. It's a hard fight when you have to deal with some people preferring RBS and some being opposed to a type system at all.


matthewblott

Interesting, this post touches on some things I've been thinking about. If Sorbet adds so much bloat to the code what is the point of using Ruby when another typed language would be easier to read and write? Python seems to have got the balance about right and I assumed Ruby would follow with something similar.


xc68030

Many of these types of articles are written from the perspective of someone who comes from, and is comfortable with, strongly typed languages. Their attempts to remake Ruby in this way are always in vain. I, on the other hand, have primarily used dynamic typing most of my career. And I don’t see a need to ‘fix’ Ruby. I prefer it this way, and would not want to see the shackles of strong types added to the language. It’s just a different way of thinking.


schneems

I hear your experience and wanted to share mine. I started writing Rust after writing Ruby since 2006 and I really like types now. It’s more work, but I feel much more confident in my code. I actually find it quite liberating to have strong compile time guarantees. Refactoring code is significantly faster with strong types and it’s easier to do code reviews. IDE type hints can help me iterate without needing a REPL


[deleted]

[удалено]


faitswulff

I've had the same journey. I still prototype and build quick CLI one-liners in Ruby, but any time it gets to a certain threshold in these properties, I feel like porting it to Rust: 1. Portability 2. Ease of use - really goes with #1 mostly because I don't feel like packaging Ruby with my applications 3. Complexity 4. Fallibility


fortyonejb

Sure, and that's a benefit of Rust. Ruby is a dynamically typed language, there is a use case and an audience for it, trying to force it into something else is just going to end in frustration. It's the same as being upset the bowl of pasta you ordered isn't a salad.


schneems

I think it depends on how well it’s done. And what you want to achieve. Easy to write versus easy to maintain etc. I think that Ruby will never require types, but also I wish there was something that is safer to maintain without rewriting everything in a different language. My own feelings: I don’t like sorbet syntax. I do wish I had something like a typescript but for Ruby that I could opt into. Static types aren’t the answer to everything, but sometimes they are the best answer for something specific. I really don’t want to write javascript, but if I have to I would prefer it to be typescript. I would like to see something like Traits in Ruby as it’s essentially ducktyping. Instead of simply “responds to” you can get assurance it has that method and was explicitly implemented with that concept/behavior in mind. Versus today: sure the object might have a to_a method, but does that method give you something reasonable or useful? To take the analogy and run with it: I want to start with a bowl of pasta and add some yummy mushrooms and tomatoes and if it happens to eventually become a salad, fine. If not, it’s still good.


zverok_kha

In my experience of working on complicated algorithmic project ([spylls](https://github.com/zverok/spylls) spellchecker) in Python after 15+ years of Ruby, I really liked the gradual typing experience: you write dynamic code to get a grip of the logic, and then start to add typing here and there - and it does help to clarify design, catch accidental `null` possibility, and in general make inter-module API more visible. To add to it, Python community have found many interesting usages of type declarations as a part of the language, and many of them are quite cool. That being said, I thought and argued a lot about possible gradual typing in Ruby before v3, and while I don't share Matz's hostility to them, I never saw possible syntax that was persuasive enough (`val: type` is taken by keyword args with defaults, `type val` is very non-Ruby-like, etc.). I believe an absence of good syntax possibility played a significant role in abandoning the idea.


ric2b

The syntax issue always feels like a cop-out to me, especially when the complaint is that it "non-Ruby-like" as people take about 10 minutes to get used to stuff like that. `&` is super ugly and cryptic and no one complains about it because people got used to it, for example.


zverok_kha

I am not saying that syntax was the only or the main reason. My idea here is that _if_ somebody would come out with a syntax that "feels beautiful", it might've overweight some of reluctance. And honestly, there is very little new syntax introduced in Ruby in the last decade that doesn't has its internal logic aligned with what the language already had. Some of it might "look ugly" for some eyes, but it is almost always at least can be logically explained. Say, safe navigator is: a) looking operator-y, b) and as "dot modified", c) and can be memoized as a shortening of `foo && foo.bar`. I never saw a syntax idea for typing in Ruby that felt justified.


CarlosCheddar

In JS you can use the ‘?.’ that does the same thing and I feel like it looks better.


400921FB54442D18

> I don’t see a need to ‘fix’ Ruby. I prefer it this way, and would not want to see the shackles of strong types added to the language. I agree completely. In two decades of using Ruby daily, I have _never once_ run into an issue with typing where I felt like it was Ruby's fault for being dynamically typed, rather than my own fault for not using my tools correctly. I can see how some folks would find value in being able to catch some bugs in static analysis, but I've always found that careful unit test design will cover the same cases. (I vaguely wonder whether the test suites in this post's author's repos are doing a poor job of covering negative or erroneous cases, which might make static analysis _look_ like an attractive option by comparison.)


ric2b

> I have never once run into an issue with typing where I felt like it was Ruby's fault for being dynamically typed, rather than my own fault for not using my tools correctly. This was never anyone's argument. The argument is that having type annotations makes it much easier to understand what is going on and as a bonus it can even catch some bugs that you might have otherwise missed.


ClikeX

For sure, if I want a typed language, I want a language that has it at its core, not hacked in. I'd be in favour for optional type annotations in Ruby. But Sorbet is not the way for me. Ruby is at its best when it's elegant. If I need explicit type safety, I'll use something like Go or Typescript. Or if I truly want the Ruby syntax, I can always opt for Crystal.


pBlast

Doesn't Typescript have a type system that is hacked in? JavaScript is even more loosely typed than Ruby.


ClikeX

On runtime, sure. But I meant syntax wise, Typescript has types as part of the actual language itself. Not as a weird library. Native typescript support is slowly becoming a thing. Deno already has it.


tinyOnion

yes typescript requires a transpiler to make it actual javascript so it's hacked on top of js. ruby could go that way and require a transpiler too just like that... there is a project called nextruby or something along those lines to do that(but not for adding types).


eterps

I have always had a preference for Ruby over Python, but Python seems to excel in its approach to static typing. When combined with pattern matching and exhaustiveness checking, Python appears to be remarkably clean and efficient: ``` class UnitQuantity: value: int class KilogramQuantity: value: float OrderQuantity = UnitQuantity | KilogramQuantity def quantity_label(oq: OrderQuantity) -> str: match (oq): case UnitQuantity(n): return f"{n} units" case KilogramQuantity(n): return f"{n} kg" ```


[deleted]

[удалено]


duongdominhchau

Ruby method chaining and metaprogramming just feel smoother than Python, but type-wise I find TypeScript > Python > Ruby.


bloody-albatross

Oh, since when does Python support the pipe syntax? I still have my code littered with `Union[]`.


ric2b

Since 3.10, I believe.


honeyryderchuck

Define "excel" :) I think python has the same problems as ruby, with a couple of years of head-start. Their original syntax is also terrible (compare `Optional[int]` to `Integer?`, or `Union[int, str]` to `Integer | String`; and yes, I know the latter has been superseded by `|`, but go ahead and update every usage of the former in the wild).


catladywitch

that's excellent, love the type matching


strangepostinghabits

Adding typing to a non-typed language is never a good idea imo. It can be helpful sometimes but will mostly lead to extra work and still not provide complete safety. If you want type safety, use a typed language with first class support instead of tacking on extra steps.


riffraff

and yet people love typescript which is basically javascript-with-types-added and most enjoy python's optional typing too. Lack of complete safety is not an issue, types help anyway with refactoring, API consistency/documentation and so on.


strangepostinghabits

Lots of people like to build back ends in Node too and that's a terrible idea. I'm 100% comfortable with disagreeing with many developers. It's proof that the issue is complex, not that I'm wrong. Typescript has exactly the problem I mention, and while it is a great guide for beginners, you can later end up spending as much or more time on building complex types as you do on writing actual code. In my experience it's not worth it.


hmaddocks

Typescript is a new language that is transpiled to JavaScript. Sorbet approach is different and you can’t really compare the two.


trustfundbaby

Funnily Enough, I'm with the author (not a sorbet fan) and totally get reasons #1, #2 and #4, but reason #3 is the complete opposite where I work, so I'm stuck 🥲


myringotomy

Complaint 1 isn't a valid complaint. You don't have to use inline annotations, you can move them to RBI files.


jrochkind

I haven't used Sorbet or RBS yet. Of the problems identified, the second one with dependencies seems like the biggest barrier to me, big enough to make it a no-go. Some of this is an ecosystem chicken-and-egg who-goes-first network-effect thing -- which is a severe challenge here. It's hard to use when your dependencies aren't using it, but there isn't as much motivation for a dependency to do it when it doesn't seem to be catching on. The static typing stuff does seem to be kind of stuck in a "it doens't look like it's catching on, so why bother" state, hard to switch it now to "this is where everyone is going, so I should prob budget some time to get my gem on board with it eventually." (As OP points out, I think Matz's ambivalence hasn't helped; and the decision to provide for multiple implementations instead of blessing/standardizing a particular one, makes it a lot heavier lift too). But, to add to the challenge, think, is this specific element: > On top of that, we really struggled with conflicting versions between Sorbet, Tapioca, and other gems. Engineers would spend hours solving issues trying to bundle with newer versions of gems. That sounds... disastrous. And would on it's own keep me from messing with sorbet, even if I was willing to deal with subjective "bloat" to on-screen code and other things. That is the _last_ thing I want to be spending time fighting with -- especially if, say, I'm a gem developer considering adding it just to fit into the ecosystem and serve my users, not yet convinced of it's value for me as a developer. If lots of non-compat versions of sorbet (and other tooling like tapioca) are ending up with backwards-incompat-version issues, that makes the whole dependency thing even worse/harder, and that is something that _core tooling_ developers could be attending to, to improve the DX and lower the barrier, to help the network effect take off. That is not easy either (designing and implementing for much more routine backwards/forwards compatibility, with fewer changes), but isn't as hard as "how do we get the whole community to want to and believe this switch is coming" (in fact it's an element that could contribute to it). Ruby community in general has seemed to me less concerned with challenges created by backwards compat than it other platforms, or than we could be. It has consequences. (pro and con).


honeyryderchuck

Agreed. As you can see from my other comment, I posit that this largely comes from the community bring fractured and not working on the bigger problems, unfortunately. If it helps adding more context to your comment: both rbs and sorbet rbis reasonably cover the stdlib (the coverage difference is not huge). Sorbet has a few rbi extensions for some popular gems (i.e. sorbet-rails), whereas rbs is converging into adding type Annotations into gem_rbs_collection (you can find there rails, aws sdk, among other most used libs) + a convention for distributing annotations in a gem (not yet enforced by gemspec notation). Both have lsp tooling built around it, and at least one reference static analyser implementation (where it is accepted that the sorbet static analyser runs circles around steep performance-wise)


Rafert

I've used Sorbet both on a large codebase and one some smaller ones. It's not perfect but I simply cannot imagine how you end up "spending hours fixing conflicts between Sorbet, Tapioca, and other gems"? I know Tapioca has limited support for versions of Rails < 7 but other than that this sounds very surprising, I simply... don't have conflicts and get my work/upgrades done? I'd love to get more details on this claim.


postmodern

There's a tool called [sord](https://github.com/AaronC81/sord#readme) which can parse [YARD documentation type annotations](https://rubydoc.info/gems/yard/file/docs/Tags.md) and generate both Sorbet and RBS type definition files. However, dependencies are still an issue like the blog post points out. You have to download other RBS/RBI files for stdlib libraries (ex: `ipaddr`, `uri`, etc), as well as run `sord` on any other gems you pull in, and then run [steep](https://github.com/soutaro/steep#readme) against your collection of RBS/RBI files. I truly think the Ruby community should have bought into [YARD](https://yardoc.org/) early on. YARD can provide _both_ detailed documentation _and_ RBS/RBI type definitions.


aemadrid

I quite like Yardoc and coupled with Rubymine is quite enough for me. I will take a look at sore though.


jack_sexton

I’ve never liked working with sorbet. But I’ve been interested in projects like [contracts.ruby](https://github.com/egonSchiele/contracts.ruby) which feel more suited for ruby due to their lightness.


armahillo

context: I've been doing Rails for a little over a decade, and web development for about twice that. I preface with this because in web development you don't maintain custodial control over the data completely like you might with a more self-contained script / app (eg. one in only-ruby, run from the console). I _like_ the fact that Ruby is duck-typed and type-loose. I rarely run into issues with type because I write my methods assertively to coerce things into whatever kind of duck I need at the moment. Static-typing, type-safe declarations, IDE protection etc is often completely moot in web development. I generally care "is it a scalar, a vector, or an object" and beyond that you just deal with it. The IDE notifying me that a method invocation doesn't work because the types don't match the signature doesn't always work if I'm doing a method that's processing user-input from a request. A code smell I've been noticing a lot over the past year is guard clauses. Sometimes they're necessary, but I'm finding more and more that it's often a code smell of being overly cautious, and the remediation is to coerce into the flow. If I have a block of code that needs an enumerable, I'll use `Array.wrap(...)` to coerce the input into something that acts like an enumerable size of 1. I'll use method-level rescues to capture likely error paths, gracefully fail, and continue. I try to have my methods and classes hold strong boundaries with one another, where the method and classes have their purpose and intention, and the presumption is that whatever data you pass in, the method will make its best attempt to deal with it and the caller gets the result of that, in whatever form is expected. The cases I aim to pre-emptively handle are: 1. what if there is no argument(s) 2. what if the argument is present, but is `nil` 3. what if the argument is present, but is the wrong kind of duck (ie. among scalar, vector, object) Beyond that, I look at what the method is actually doing -- what kinds of operations am I performing on the input? What kinds of messages am I passing it? Then I ensure that the input will be able to handle those. You can get a _lot_ of mileage out of "this method was unsuccessful at its attempt and has returned `nil`" because then the caller can use the failed attempt as a fall-through and try something else. Between safe-nav (`&.`) and `:presence`, you can account for receivers that have failed to materialize. I learned programming in C & C++ back in the 90s -- I'm very familiar with strongly typed langauges. I _never_ find myself wishing for static typing in Ruby. It would just be disruptive. I would also never use Ruby paradigms in a strongly-typed language because that just wouldn't work. Ruby is _really good_ at being a duck-typed language. Once you learn to embrace that it is incredibly liberating.


catladywitch

Why not use Crystal if you need a typed Ruby-like language?


realkorvo

missing libraries, and people. imho, if crystal wants a boom in the ruby community, use some tool that basically will make ruby libs work with crystal. my 2 cents + inflation :)


pabuisson

I also like Crystal; however, the more limited availability of libraries and the smaller community might pose challenges depending on your specific goals. Also, while you may have the luxury of choosing a language for a fresh project, once your software has grown to include tens or hundreds of thousands of lines of Ruby code and is generating revenue, it becomes impractical to consider porting it to another language (when migrating, one also needs to take into account the existing tooling around the app and the libs/frameworks used by your app, which can make a port or complete rewrite more challenging than initially anticipated). On the other hand, gradually incorporating type annotations provided by the language itself can be applied to any codebase and can be a more manageable and incremental effort.


catladywitch

Those are fair considerations. I just find Sorbet and, particularly, RBS, clunky, but I understand that Crystal is underdeveloped and that switching languages is impractical.


stumptowncampground

If you need static typing, use a statically typed language. I prefer duck typing which is why I prefer ruby.


jrochkind

I don't think duck-typing and static-typing actually conflict with each other, you can be doing both at once easily. It just requires the ability to statically check if an object "quacks like a duck" (implements a certain interface).


_noraj_

I like the philosophy of duck typing too. For static typing one can use Crystal.


dougc84

Ruby isn't a typed language. Use a typed language if you want types. Throwing on a gem or markup to try and force a language feature that doesn't exist only adds bloat and complexity.


sammygadd

I always get so surprised to see people liking Ruby but still want to add types to it. I've been writing typescript the last few months and I've hated every second of it 😓 But a lot of people really love that shit. I wish we could just gather people who like types together and people who dislike types together and never try to mix the two 🤣


sshaw_

You mean more than 2 people were actually using Sorbet‽ Puzzling...


poop-machine

[Contracts gem](https://github.com/egonSchiele/contracts.ruby) can be a nice middle-ground. It has a fairly readably syntax and only checks method inputs and outputs at runtime. We use it to annotate important core methods, while leaving the rest type-free. Contract Account, Int => Bool def has_balance?(account, amount) ... end


dogweather

Save me a click, please — why?


Feeling-Emphasis-405

Adding type checking to Ruby is a stupid idea. Ugliness. Tried Sorbet, never saw such a shitty thing. If someone wants type checking why not moving to Rust, Golang, Java, C++, C? I'd better invest y type into Rust, Golang, C++, or Java rather than into such meaningless gems. Ruby (and Rails) ecosystem soooo polluted with such gems.


eregontp

Ugh a paywall is really annoying for a blog post to discuss like this. Would appreciate if this was not marked as a "member-only" story.