Talks

Lightning talk: Conventionally-typed Ruby

Lightning talk: Conventionally-typed Ruby

by Josua Schmid

In this lightning talk from Helvetic Ruby 2023, Josua Schmid introduces the concept of "conventionally-typed Ruby," exploring a new perspective on typing in Ruby programming. The discussion highlights the distinctions between statically typed and dynamically typed languages, while proposing that the emphasis should not solely be on type systems but rather on human understanding and interaction in coding.

Key Points Discussed:

  • Dynamic Typing in Ruby:
    • Ruby is inherently a dynamically typed language, meaning that type errors are caught at runtime rather than at compile time. For example, adding a float to a string will raise an error when the code runs.
  • Recent Changes with Ruby 3:
    • With the introduction of RBS files in Ruby 3, developers can now declare types externally, allowing for pre-runtime type checks and compile-time errors through tools like Steep or Sorbet. However, Josua expresses a preference against heavy configuration, indicating that this complexity can detract from the focus on solving business problems as a Rails developer.
  • Critique of Type Annotations:
    • Josua argues against the necessity of type annotations in Ruby, emphasizing that the language's design prioritizes simplicity and developer autonomy.
  • Proposal for Conventional Typing:
    • He proposes the idea of conventional typing, where understanding of types would derive from the context within the code rather than explicit annotations. This could be seen as a guessing game where developers infer types based on naming conventions and runtime observations.
  • Avenues for Exploration:
    • Several methods for implementing this conventional type system are discussed, such as:
    • Analyzing variable names at runtime to develop a better understanding of data types used.
    • Using existing tools like Rubocop or language models to develop a dictionary of type conventions.
    • Future considerations include how to integrate nullable types effectively.
    • There's potential for extending current typing tools like Sorbet or Steep to infer types from naming alone, instead of relying on explicit annotations.

Conclusions:

  • Josua notes that while there are many questions that remain unanswered regarding conventional typing, this approach seeks to bridge the gap between human understanding and technical constraints within Ruby.
  • He invites feedback on his ideas and references a blog article he wrote four years ago on this topic, encouraging further discussion among attendees.

In summary, the talk encourages exploring the human element of programming and suggests that embracing conventions in Ruby's dynamic typing can lead to more intuitive code practices, fostering a stronger connection between developers and their code.

00:00:05.720 Hello everyone, my name is Joshua. I work for Ruo, and I have a lot of ideas, but just not enough time.
00:00:08.679 So, I've decided to take up your time to think about my idea, which is a chaotic proposal to reframe the entire typing discussion: statically typed, dynamically typed, weakly typed, strongly typed... it doesn't all matter so much if we consider that we are all human.
00:00:19.800 First, a short introduction: Ruby is a dynamically typed language. This means that when we give the interpreter some code, it performs semantic analysis and will let us know at runtime if there is a type mismatch. For example, it will complain that a float cannot be added to a string.
00:00:40.239 Since Ruby 3, types can also be declared in RBS files outside of Ruby, which means we can now check for type signatures before the code actually runs. With tools like Steep or Sorbet, we can provoke compile-time errors to help us avoid stumbling during runtime. However, I find this configuration unnecessary because, as a Rails developer, I don't like configuration at all.
00:01:07.920 I'm very happy that Matz did not implement annotations in my beautiful Ruby. This allows me to focus on my business problems without having to think about machine problems. There are discussions about whether type annotations are for humans as well. Are they really? Personally, I don't want to delve too deep into this heated debate. For me, it's still all about configuration.
00:01:41.759 I want to propose another solution called conventional typing. We often read type annotations when we look at Ruby code. Let’s make it a guessing game: what types do you think these variables or method names actually are? We can all agree that there’s a class called Numeric. There may exist a function that returns a Boolean, which still doesn't exist in Ruby, like a DateTime include function.
00:02:04.360 The challenge now is knowing how we get from the left side to the right. There’s an RBS prototype that can make RBS files, but we don’t have this for conventional types. I have some, let’s say, naive or basic ideas, and you probably have better ones. Perhaps we could look at our variable names during runtime and record what we see? We could discover our conventions over a fully covered test suite for our projects.
00:02:50.760 Alternatively, we could also build a dictionary using the Par of Gem or Rubocop, or maybe even involve language models in that effort. Naming is a complex problem, and we tackle it continuously.
00:03:01.800 Some questions that remain open regarding conventional typing include how we handle nullable types. The variable name alone cannot account for nil. Can we perhaps extend Sorbet or Steep to drop type annotations and instead look at the names of variables and methods? What even are linters or contracts?
00:03:37.759 These topics could also be included in the typing discussion. My proposal originated from a blog article I wrote four years ago. You can read it if you like and feel free to comment. Thank you very much!