The fun thing about how Sorbet works: the same architecture that powers parallel execution (for batch speed ups) is the thing that powers fast, incremental IDE mode.
The columns represent parallel execution (at the file level). The three big boxes represent fork and join points. So for example, the first large box (index) and the last large box (typecheck) are trivially parallelizable at the file level, and there's a small, tightly controlled resolve step that can't* be parallelized.
But it's also a picture of Sorbet's IDE pipeline, where the columns represent incrementality. If no other file (column) changed, that work is already cached.
This keeps things really simple because:
- Most speedups make both the batch mode and the incremental mode faster
- The same code paths are 100% re-used between the batch mode and the IDE mode
- Bugs that are "IDE-only" are rare. You can almost always reproduce a bug in the IDE mode as a bug in the batch mode if you squint at the problem hard enough.
The article says something like this:
> The main drawback of this approach is that it works only when it works — not every language has a well-defined FQN concept.
Sorbet was designed from the very beginning to support a type system for Ruby that wasn't maximally expressive nor maximally faithful to existing Ruby code. It was designed to make editor tools super easy to build and maintain. There are plenty of places where this shows through to the user in not great ways, but the benefits of a fast, reliable IDE mode generally out shine them.
*: This doc is actually out of date; there are ways to parallelize parts of it that have been implemented.
https://github.com/sorbet/sorbet/blob/master/docs/pipeline.m...
^ This is a picture of Sorbet's batch pipeline.
The columns represent parallel execution (at the file level). The three big boxes represent fork and join points. So for example, the first large box (index) and the last large box (typecheck) are trivially parallelizable at the file level, and there's a small, tightly controlled resolve step that can't* be parallelized.
But it's also a picture of Sorbet's IDE pipeline, where the columns represent incrementality. If no other file (column) changed, that work is already cached.
This keeps things really simple because:
- Most speedups make both the batch mode and the incremental mode faster
- The same code paths are 100% re-used between the batch mode and the IDE mode
- Bugs that are "IDE-only" are rare. You can almost always reproduce a bug in the IDE mode as a bug in the batch mode if you squint at the problem hard enough.
The article says something like this:
> The main drawback of this approach is that it works only when it works — not every language has a well-defined FQN concept.
Sorbet was designed from the very beginning to support a type system for Ruby that wasn't maximally expressive nor maximally faithful to existing Ruby code. It was designed to make editor tools super easy to build and maintain. There are plenty of places where this shows through to the user in not great ways, but the benefits of a fast, reliable IDE mode generally out shine them.
*: This doc is actually out of date; there are ways to parallelize parts of it that have been implemented.