It's not always a good thing, but I love Ruby's ability to define new runtime-valid syntax that looks pretty much native to Ruby itself.
def method(thing: String | "default value")
the pipe operator seems to be defined here, as just a regular method: https://codeberg.org/Iow/type/src/commit/aaa079bf3dd2ac6b471... the type gets picked out by the module included in the class you want typechecked, which reads the default value from all methods (which is the "real" ruby syntax here, where `thing` is assigned a default value of the result of calling `String | "default value"`) and uses that for type checking.
I like that over-flexibility... it's regularly too clever and makes it difficult to follow the flow of an application, but I like it all the same.
Though the ability to arbitrarily create first class syntax is why Rails is Rails, my favorite use case is FizzBuzz as a property of Integers. YMMV.
Mixed feelings here. Type annotations are a thing Ruby lacks, that other languages have, that I like using in other languages. Ergo, I'd like to have them in Ruby, right?
My knee-jerk reaction is "yes I'd like that" but when I pause to think about how I actually write Ruby code... hmm. I tend to use Ruby when its flexible syntax and type system are helpful. How much would I actually benefit from something that restricts the flexibility of the type system?
Bear in mind, I'm not a "Ruby dev" per se. It's a well-loved tool in my mostly firmware-focused repetoire. I use it for little CLI tools, and toy game engines too (mri embeds into C really cleanly). Fun little things that most folks would use Python for, I just like Ruby better.
I had exactly this reaction when gradual typing came to Python. "Do we really need this??"
But over time, I've grown to love it. Programming is communication—not just with the machine, but with other developers and/or future me. Communicating what types are expected, what types are delivered, and doing so in a natural, inline, graceful way? Feels a big win.
Ruby has had "officiak" type annotations since 3.0.0 via RBS.
Exactly because of the concerns you described, RBS originally used only separate files for the type annotations, so it can be selectively and gradually applied. You can add Ruby signatures inline as comments as well, but frankly both options looks ugly, and so does many of the alternatives like Sorbet signatures.
I love these new approaches to type checking such as this and Literal[1]. I think they really show how far we could go with runtime ruby syntax.
For both though I have questions:
A. How do I use this day to day to improve my tooling and developer experience?
B. If at some point in the future I decide to get rid of this how easy is it to eject?
I've seen too many adandoned dependencies over the years to trust anything I can't easily remove when it's time to upgrade.
These runtime typing efforts look nicer than Sorbet but, as far as I can see, you still have to have complete test coverage to trigger runtime checks if you want to spot correctness issues before you deploy into production.
Sorbet doesn't have that problem right now. Maybe something clever using Prism might be a way round that?
They should integrate this to ruby-core and make it even better by changing the parser and making it faster in terms of performance.
But I have a hard time believing ruby-core will want to hear community feedback... Ruby is omakase?
RBS and Sorbet suck. One is very limited, the other isn't part of ruby-core and makes you rewrite the function arguments again, similar to Java's annotations... Doesn't look like Ruby at all, or DRY, mostly like a workaround!
It's not always a good thing, but I love Ruby's ability to define new runtime-valid syntax that looks pretty much native to Ruby itself.
the pipe operator seems to be defined here, as just a regular method: https://codeberg.org/Iow/type/src/commit/aaa079bf3dd2ac6b471... the type gets picked out by the module included in the class you want typechecked, which reads the default value from all methods (which is the "real" ruby syntax here, where `thing` is assigned a default value of the result of calling `String | "default value"`) and uses that for type checking.I like that over-flexibility... it's regularly too clever and makes it difficult to follow the flow of an application, but I like it all the same.
Though the ability to arbitrarily create first class syntax is why Rails is Rails, my favorite use case is FizzBuzz as a property of Integers. YMMV.
Mixed feelings here. Type annotations are a thing Ruby lacks, that other languages have, that I like using in other languages. Ergo, I'd like to have them in Ruby, right?
My knee-jerk reaction is "yes I'd like that" but when I pause to think about how I actually write Ruby code... hmm. I tend to use Ruby when its flexible syntax and type system are helpful. How much would I actually benefit from something that restricts the flexibility of the type system?
Bear in mind, I'm not a "Ruby dev" per se. It's a well-loved tool in my mostly firmware-focused repetoire. I use it for little CLI tools, and toy game engines too (mri embeds into C really cleanly). Fun little things that most folks would use Python for, I just like Ruby better.
I had exactly this reaction when gradual typing came to Python. "Do we really need this??"
But over time, I've grown to love it. Programming is communication—not just with the machine, but with other developers and/or future me. Communicating what types are expected, what types are delivered, and doing so in a natural, inline, graceful way? Feels a big win.
Ruby has had "officiak" type annotations since 3.0.0 via RBS.
Exactly because of the concerns you described, RBS originally used only separate files for the type annotations, so it can be selectively and gradually applied. You can add Ruby signatures inline as comments as well, but frankly both options looks ugly, and so does many of the alternatives like Sorbet signatures.
I love these new approaches to type checking such as this and Literal[1]. I think they really show how far we could go with runtime ruby syntax.
For both though I have questions:
A. How do I use this day to day to improve my tooling and developer experience?
B. If at some point in the future I decide to get rid of this how easy is it to eject?
I've seen too many adandoned dependencies over the years to trust anything I can't easily remove when it's time to upgrade.
These runtime typing efforts look nicer than Sorbet but, as far as I can see, you still have to have complete test coverage to trigger runtime checks if you want to spot correctness issues before you deploy into production.
Sorbet doesn't have that problem right now. Maybe something clever using Prism might be a way round that?
1. https://literal.fun/
[dead]
They should integrate this to ruby-core and make it even better by changing the parser and making it faster in terms of performance.
But I have a hard time believing ruby-core will want to hear community feedback... Ruby is omakase?
RBS and Sorbet suck. One is very limited, the other isn't part of ruby-core and makes you rewrite the function arguments again, similar to Java's annotations... Doesn't look like Ruby at all, or DRY, mostly like a workaround!