📄 Ruby Sorbet is too verbose, can the syntax be improved?
29th October 2024
Awhile back when I was ramping up on Typescript, I was leaning into the benefits of types. In the Ruby world, Sorbet is the most common way to add types so I gave that a shot. In the end, I ripped it out. I spent more time wrangling type checking then the time it spent catching bugs, and one of the issues was the verbose syntax. But recently I came up with a novel solution to this problem. First, here is the verbose syntax — you end up declaring all your arguments twice:
sig { params(name: T.untyped, nickname: String).returns(Integer) } def greet(name, nickname) puts "Hello, #{name}! Your nickname: #{nickname}" name.length end
It may not seem like a big deal, but every time you change the name of an argument or change the order, you have to do it in two places. Recently I had an idea: could we do it in one line if we used Ruby to redefine how methods are defined? I got this syntax working and threw it up on a gist:
# Two positional arguments. The first, name, is untyped. # The second, nickname, must be a String df :greet, :name, nickname: [String], returns: Integer do puts "Hello, #{name}! Your nickname: #{nickname}" name.length end
Here is a gist. It supports positional and named arguments. I got it working with runtime and static analysis. I don’t plan to take this experiment any further right now, but maybe it’s useful to someone.
More recent articles
- Rails migrations can include an up_only part - 29th October 2024
- Ruby can chain methods and right-assign - 29th October 2024