RBS

The State of Ruby 3 Typing

The State of Ruby 3 Typing

by Soutaro Matsumoto

The video titled "The State of Ruby 3 Typing," presented by Soutaro Matsumoto at RubyKaigi Takeout 2020, focuses on the introduction of a new feature in Ruby 3 known as RBS (Ruby Signature). This feature aims to enhance type checking within Ruby programs by allowing developers to declare types using a dedicated language.

Key points discussed in the presentation include:

- Introduction to RBS: RBS serves as both the language for declaring types and a gem included with Ruby 3, facilitating the reading, writing, and processing of type definitions. It includes pre-defined type declarations for standard library classes.
- Availability of Type Checkers: Notably, Ruby 3 will not ship with a default type checker, giving developers the freedom to choose the most suitable type checker for their projects. Some prominent type checkers mentioned are:
- Steve: A Ruby-written type checker developed by the speaker.
- Sorbet: Currently popular within the Ruby community.
- Type Profiler: A tool that infers types without explicit annotations.
- RDL: A research tool led by academic professionals focusing on type checking.
- Static Type Checking: Matsumoto illustrates the benefits of static type checking using practical Ruby code snippets, emphasizing how it can clarify method expectations and preemptively catch errors that would otherwise require runtime execution to identify.
- RBS Language Features: By enabling developers to define types externally, RBS enhances clarity regarding method arguments, return types, and class structures. Examples such as the Conference class highlight the ease of understanding method interfaces through RBS.
- Advanced Type Support: RBS accommodates complexities such as generics, union types, optional types, and duck typing, which significantly enrich the type system and promote precision in type definitions.
- Community Adoption and Future Outlook: The video expresses a belief that while static typing via RBS is a progressive step in Ruby's evolution, it should remain an optional practice to allow developers to gradually integrate typing into their workflows.

In conclusion, RBS represents a significant enhancement to Ruby's typing capabilities, aiming to bridge dynamic Ruby programming with the benefits of static typing. Developers are encouraged to adopt RBS to improve code quality without enforcing rigid typing structures within their projects. Soutaro Matsumoto ends with an invitation for questions and feedback, reiterating the importance of community engagement as Ruby 3 and RBS evolve.

00:00:01.199 Hello, my name is Soutaro Matsumoto. I am an engineer working for Square in Tokyo. I write some Rails applications and I'm also working to improve the development environment. I developed a type checker called Steve and I'm running an experiment to test Steve with some of the projects in the company. Additionally, I'm a member of the Adobe community team and I'm working on types in the team as well.
00:00:15.679 The topic of my talk today is the state of Ruby 3 typing. Ruby 3 will ship with a new feature called RBS to support type checkers. RBS is both the name of the language used to declare types in Ruby programs and the name of an Adobe gem bundled with Ruby 3. This gem provides features to read, write, and process type definitions written in RBS, and it includes type definitions for standard library classes.
00:00:41.920 You can start using the standard library and its type definitions just after installing Ruby 3. One important note is that Ruby 3 won't provide a standard type checker. The Ruby core team is not attempting to endorse a single 'best' type checker, so you will need to choose the best type checker for your team and project.
00:01:02.159 I would like to introduce some type checkers for Ruby that you can choose from. Steve, which I mentioned earlier, is a type checker written in Ruby. Sorbet is currently the most widely used type checker for Ruby. You may find discussions on its usage within the Ruby community. Another option is Type Profiler, which infers types in programs without any explicit type annotations.
00:01:32.799 RDL is another project that serves as a research tool in development. The team is led by Professor Foster, who has published research papers on type checking for Ruby using this tool. These papers are quite interesting, and I encourage you to check them out online. Therefore, we have at least four type checkers available for Ruby.
00:01:52.240 Now, let's discuss the idea of static type checking. Consider an example Ruby program that prompts several questions. For instance, if there is a new method called `unconference_constant`, a question arises: does this method accept a string argument, or does it require other arguments? Similarly, when looking at the `talks` method, which uses the `push` method of an array, you might wonder about the return type of the `talks` method. It appears to return an array, but we can't be certain.
00:02:21.440 Furthermore, the `each_speaker` method suggests it accepts blocks, but the type of block arguments is uncertain. Perhaps it expects an instance of a speaker, but again, we can't be sure without the correct type definitions. Questions like these illustrate why static type checking is beneficial; it would return answers without executing the Ruby program.
00:02:39.600 If we execute the Ruby program, the interpreter will give answers based on the provided code. For example, it will raise an ArgumentError if required arguments are missing. Other exceptions may arise if there are method naming errors. However, identifying type problems statically rather than through execution would be a significant improvement.
00:03:06.720 RBS can assist with static type checking by clarifying methods' expectations and preventing potential runtime errors. The RBS language allows developers to define types for Ruby applications including classes, modules, methods, and the relationships between them. In essence, RBS acts as documentation for what types are available and how they should be used in Ruby code.
00:03:40.720 To illustrate the utility of RBS, consider the `Conference` class as an example. It has two read-only attributes, `name` (a string) and `talks` (an array of Talk objects). The `schedule` method accepts one string argument, while the `each_speaker` method expects a block to operate on, indicating the structure and type relationships throughout the class.
00:04:00.480 Using RBS for the Conference class allows developers to ascertain the return types and expected method arguments at a glance, which is invaluable for development. By having well-defined interfaces, we can quickly identify how to interact with different objects, providing a clearer documentation of the code.
00:04:20.720 RBS is not limited to simple classes; it can be applied to the standard libraries. For example, you may find RBS files for the String class, detailing the methods and their respective types. Through various advanced types supported in RBS, we can implement generics, union types, and optional types, allowing for flexible and precise type definitions.
00:04:44.080 The concept of generics means we can define a type that takes other types as parameters, such as an array of integers or a hash with string keys and integer values. Union types let us specify a value that can be one of several types, while optional types provide shortcuts for expressing variables that may be nil. Additionally, we have support for duck typing, allowing a type to represent any object that implements specific methods regardless of inheritance.
00:05:53.600 In RBS, there is a special type known as 'untyped,' which indicates that the type checker will not perform any checks on that type, akin to the `any` type in TypeScript. More examples and detailed specifications can be found in the RBS repositories, which contain RBS files for standard libraries, thus making it easier for developers to use.
00:06:32.000 The language RBS itself is designed to enable better type checking in Ruby applications. It facilitates the definition of types outside of the Ruby code, accounting for projects implemented in the C language, such as the Ruby standard library. The architects of RBS believe that modular type development and clear interface definitions are paramount for Ruby's ongoing evolution.
00:07:26.400 The RBS library aids developers in creating type checkers without constraining them to a fixed type definition format. It allows developers to focus on core features while it manages the complexities of type declarations. Tools like RBS must offer compatible interfaces across multiple type checkers while ensuring ease of adoption within existing projects.
00:08:45.920 Expect that as Ruby continues to evolve, so too will RBS and the community's perception of static typing. Eventually, developers may rely more heavily on static type definitions to prevent runtime errors before they occur. However, these practices should remain optional, encouraging developers unfamiliar or uncomfortable with types to ease into the concept.
00:09:29.680 Ultimately, the RBS project aims to be a bridge between dynamic Ruby programming and the advantages of static typing, contributing positively to developer experience and application reliability. It represents a significant advancement in Ruby language features and brings new opportunities for enhancing code quality.
00:10:11.679 As Ruby 3 rolls out, expect RBS files to be a staple in modern Ruby applications. Each Ruby application should take advantage of RBS for documenting standard libraries and the specific types used. Keeping types in separate RBS files helps enhance code understanding and limit errors without forcing adoption of strict typing policies at the project level.
00:10:49.440 Thank you for watching my presentation. While I believe RBS is an exciting addition to Ruby, I also recognize there are challenges and gaps that still need to be addressed. Please feel free to reach out to me on Twitter or GitHub if you have any questions or feedback. I appreciate your time.