Clarifying the README about find, first and last
eregon opened this issue · comments
Currently, the README says:
Sorbet does not allow us to define multiple signatures for a function.
But it seems to work for Enumerable#first for instance, and the definition in Sorbet uses multiple signatures for a function: https://github.com/sorbet/sorbet/blob/119e937e9e3b03ec27308cd8874f482791d15864/rbi/core/enumerable.rbi#L167-L174
Probably that was in an earlier version of Sorbet and now it could work out of the box?
Sorbet only supports overloading for stdlib but intentionally limiting to not be used in other definitions.
Since we want to type find
, first
, last
with proper return type, we override the original sigs in Enumerable.
Here is a full context from @DarkDimius
Our overloading is very limited and build "just enough" to support stdlib. It doesn't work in runtime typechecking at all. We don't intend to continue building it out.
What we use internally for legacy methods like that is either:
- make them return
T.untyped
and take aT.any
of potential argument types. You'll get static and > runtime typechecking of arguments, but not result type- make them return
T.any
or potential result types and take aT.any
. This requires modifying callers.Neither of those options are great, but we currently are skeptical of us being able to support overloading well in userland.
If you're interested in underlying skepticism of us being able to support it: many people are coming at this from static language perspective, where a static typechecker decides which of those methods will be called ahead of time, and "compiles" this knowledge into runtime, commonly called overloading. That's not how ruby works, in ruby, many methods decide this in runtime, not statically. Ruby has multimethods. Even in languages that started with a typesystem this frequently creates more problems that solves. Of languages that do use it, the most common is Julia.
https://sorbet-ruby.slack.com/archives/CHN2L03NH/p1558029143153100
I added a note to the readme in #20. Thanks for the great question!
I'm going to close the issue but please feel free to reply if you have more question.
Thanks for the quote, that explains some of it.
I find it surprising that the exact syntax used for typing Enumerable doesn't work outside, and therefore that external type definitions are less flexible/powerful than those of stdlib, but I guess that's something to ask on Slack or to @DarkDimius.