00:00:04.319
It's time for the awesome Matz to give us the keynote, so let's get started and welcome him.
00:00:28.960
Welcome to the stage!
00:00:34.530
Giving a keynote in English makes me nervous every time, but I believe I can manage.
00:00:43.600
In recent years, we have been working on something called Ruby 3.
00:00:50.000
Ruby 3 represents the future of Ruby. However, you will not see Ruby 3 this year or next year; it's a vision for the distant future.
00:01:00.039
In that sense, Ruby 3 is currently more of a concept than a reality.
00:01:08.080
Since it is just a vague notion, we must acknowledge that these ideas are fragile, but we need some goals to aim towards in order to advance the Ruby community.
00:01:22.759
Especially for the Ruby community, setting clear goals is essential for progress.
00:01:30.520
A very important aspect of the future Ruby is that it should remain compatible with current Ruby versions.
00:01:40.159
We experienced a huge gap when we transitioned from Ruby 1.8 to 1.9, which was very challenging.
00:01:48.280
We needed to support multiple encodings and better Unicode support during that transition.
00:01:54.880
We want to avoid such pain in the foreseeable future.
00:02:01.119
So, despite the fact that we are trying to introduce many dramatic features in Ruby 3, we will strive to maintain compatibility with the existing versions.
00:02:08.759
The key features of Ruby 3 will focus on performance, concurrency, and typing.
00:02:14.680
For performance, we have a slogan: "Ruby 3 x 3," meaning that Ruby 3 will be three times faster than Ruby 2.
00:02:20.840
That sounds great, right? We are working on optimizing the garbage collection (GC), improving the virtual machine (VM), and other optimizations.
00:02:27.760
We are also investigating the introduction of Just-In-Time (JIT) compilation to the Ruby virtual machine.
00:02:35.720
However, making Ruby three times faster is not an easy task.
00:02:42.000
We've been developing Ruby and its interpreters for more than 20 years, and we have already optimized many easy targets.
00:02:49.080
Because of that, achieving a threefold increase in speed will be quite a challenge.
00:03:04.120
We compare Ruby 3 to Ruby 2.0, which is a version that's about three years old, and we've improved Ruby consistently.
00:03:17.840
For instance, each year since Ruby 2.0, we've introduced improvements at a rate of 5 to 10%.
00:03:30.040
Each version is designed to be faster than the previous one.
00:03:41.880
Hence, we aim to include all of those efforts in Ruby 3, even though not everything can be three times faster.
00:03:56.600
We will choose specific benchmarks where Ruby 3 will run faster than Ruby 2.
00:04:01.360
These benchmarks will be small; we don't want to install large frameworks or huge applications for testing.
00:04:07.159
However, they should not be overly simplistic, like calculating factorials.
00:04:15.360
We want realistic benchmarks that reflect actual performance improvements.
00:04:24.240
Now, let's discuss concurrency. I started designing Ruby in 1993, and back then, computers only had one CPU.
00:04:40.360
That meant we didn’t have to worry about threading or parallelism since there was only one execution thread at a time.
00:04:55.360
Because of that, I only considered concurrency and added threading to the language.
00:05:01.360
But I didn't give much thought to parallelism.
00:05:07.360
Today, however, we are living in a multi-core age with dual-core, quad-core, and octa-core CPUs in laptops and smartphones.
00:05:14.400
Everyone wants to leverage concurrency and parallelism.
00:05:20.960
People want to utilize concurrency and parallelism through threading.
00:05:29.759
But we face challenges with threading, especially in Ruby, due to the Global Interpreter Lock (GIL).
00:05:37.560
Due to the GIL, only one thread can run at a time in the Ruby virtual machine.
00:05:43.000
So, there is no true parallelism, even on multi-core machines.
00:05:55.360
This creates a trade-off between performance and safety. Multicore machines can perform better, but threading introduces complexity.
00:06:03.600
Managing threads independently while ensuring synchronization is quite challenging.
00:06:09.440
By changing a few lines of code, it's possible to remove the GIL from the Ruby virtual machine.
00:06:16.000
However, your threaded program will likely crash if you try that.
00:06:25.360
We prioritize safety in the Ruby virtual machine.
00:06:32.000
Threading can be considerably complex without the right language features, unlike languages like Elixir.
00:06:42.000
For this reason, we concluded we need better abstractions for concurrency.
00:06:54.399
We investigated various models: the actor model, streaming model, and ownership model.
00:07:05.760
Last year, I discussed the concurrency topic in my keynote, particularly focusing on the streaming model.
00:07:12.800
However, we decided to abandon the streaming model and have opted for a form of the ownership model with slight modifications.
00:07:24.880
This model needs a name, so we are looking for a suitable term.
00:07:35.320
Kichi, who is in charge of the virtual machine, has been searching for this concept for years.
00:07:49.600
Finally, we came up with a name for this idea: ‘Guild.’
00:07:55.080
A guild represents a community of craftsmanship, reminiscent of role-playing games.
00:08:01.320
In this guild model, each object is a member of a guild, and you can transfer the membership of an object to another guild.
00:08:14.479
However, objects must be moved instead of copied, and such transfers can occur via channels.
00:08:21.040
Think of it like goroutines, with some abstractions layered on top of the current Ruby model.
00:08:28.000
It resembles the actor model and shares minimal mutable state.
00:08:37.360
While classes and modules can be shared, we will still have the GIL.
00:08:45.760
Each guild is isolated, allowing multiple guilds to run in parallel.
00:08:55.360
Within a guild, you can still have threads, but only one thread can run at a time.
00:09:06.320
This concurrency model ensures that different guilds can execute in parallel, enhancing performance.
00:09:17.320
We provide a better abstraction for concurrency while maintaining compatibility.
00:09:24.000
This approach should reduce bugs in the system.
00:09:35.120
We've moved away from the streaming model and instead experimented with that model in another language I created called Stream.
00:09:43.079
This is my personal toy language featuring the streaming model available on GitHub.
00:09:55.599
Now, let’s move on to the final and biggest topic of this keynote: typing.
00:10:03.680
In this decade, we have seen the rise of many new programming languages, most of which are statically typed.
00:10:14.000
Examples include TypeScript, Flow, Go, and Swift. Statically typed languages have gained a lot of popularity.
00:10:27.520
I often hear hostile claims that Ruby is dead because it lacks static typing.
00:10:36.239
Who really cares? We should not be swayed by technological trends that come and go.
00:10:45.680
For example, during the 1980s, dynamically typed programming languages like Lisp and Smalltalk were very popular.
00:10:55.840
Eventually, many developers shifted towards statically typed object-oriented languages like Java.
00:11:04.560
Yet, some developers from the Java world later transitioned to Ruby and JavaScript.
00:11:12.960
And now we see some of those developers moving toward statically typed languages like Swift and Go.
00:11:25.600
This cycle of migration happens roughly every decade.
00:11:33.840
What does the future hold? It's possible that we will see a shift towards statically typed languages again.
00:11:46.239
As front-liners, we must think about the future of dynamic typing.
00:11:53.440
So, what does typing mean in dynamically typed programming languages like Ruby?
00:12:00.239
In statically typed languages, a class is a type, but in Ruby, the class is not necessarily a type.
00:12:10.680
We have a principle called duck typing.
00:12:18.960
Duck typing suggests that if something behaves like a duck, it is treated as a duck.
00:12:28.320
In other words, we ignore inheritance or internal structure and focus on behavior.
00:12:37.440
In Ruby, we care about how things behave rather than the details of how they are implemented.
00:12:45.520
Thus, duck typing is the Ruby way, where simplicity and ease of use are prioritized.
00:12:52.400
Dynamic typing allows us to ignore unnecessary formalities and reduces cognitive load.
00:13:02.640
Our mental resources are limited, so we should conserve them.
00:13:10.080
For example, when we need a logging function, we might use a string to log messages.
00:13:19.920
In a statically typed version, we might need to provide type annotations.
00:13:27.920
But in Ruby, we can create a StringIO to log messages and retrieve them easily.
00:13:34.800
However, in the static typed world, that would fail because StringIO and other types do not share a common ancestor.
00:13:41.680
This is where duck typing shines: it allows flexibility and reduces mental costs when developing programs.
00:13:49.600
Furthermore, duck typing leaves room for ambiguity, making it easier to represent behaviors without strict rules.
00:13:58.440
In Ruby, a type is not nominal; instead, it's defined by the expected behavior.
00:14:06.240
We don't need exact names or strict inheritance hierarchies.
00:14:16.080
Although we can call for more expressive interfaces, that often causes unnecessary limitations.
00:14:23.360
In Ruby, we prioritize 'Don't Repeat Yourself' (DRY), which means avoiding redundancy.
00:14:36.640
If you can execute a program without some factors, you should remove them.
00:14:48.320
Currently, dynamic typing implies that we don’t need to repeat type annotations.
00:15:01.120
While dynamic typing has its downsides, such as discovering errors only at runtime, this can promote better development practices.
00:15:10.240
Nonetheless, dynamically typed languages often produce less clear error messages.
00:15:20.400
For example, receiving an error message like ‘undefined method for a new class' can be frustrating.
00:15:31.760
With class annotations, documentation suffers as well, as we often only provide type information in comments.
00:15:42.560
While static typing can be productive, it contradicts the essence of Ruby.
00:15:51.040
While it would look like we are incorporating static typing without truly enforcing it, the essence of Ruby lies in its flexibility.
00:16:00.320
As engineers, our goal is to find solutions without unnecessary complications.
00:16:11.320
One solution is type inference, seen in languages such as Scala or OCaml.
00:16:18.320
Type inference allows the compiler to determine variable types without explicit annotations.
00:16:26.320
This strikes a balance between flexibility and type safety.
00:16:34.320
The compiler can catch more errors during compile time, combining the benefits of dynamic and static typing.
00:16:41.760
For instance, we can simplify the Go interface example with inferred types, which closely resembles Ruby's dynamic typing.
00:16:50.240
This gives us a sense of dynamic inference, defined by behavior instead of strict naming.
00:16:59.440
In Ruby, inferred types are not necessarily linked to class names; they represent expected behavior.
00:17:05.680
However, inference isn't perfect. For example, we may encounter situations where one object conforms to a type but lacks others.
00:17:14.240
Duck typing doesn't guarantee full coverage like suggestive static typing can in other languages.
00:17:22.960
Still, we achieve more reliable typing in Ruby through inference, reducing the chances of error at runtime.
00:17:30.720
We can incorporate ad-hoc type information for error detection, allowing runtime analysis.
00:17:38.720
By combining known type behaviors from specific objects, we can check type compatibility.
00:17:46.400
For example, if a method requires a particular type of argument, the system should recognize this and provide feedback.
00:17:55.040
Also, runtime type information allows for more profound insights, improving the developer experience.
00:18:04.480
By collecting data on argument types, we can create a type database for our applications.
00:18:12.800
This knowledge can enhance our coding experience, enabling better productivity tools in the future.
00:18:20.640
This is still in the conceptual phase, but we're actively researching these improvements.
00:18:30.160
It's crucial for Ruby to keep evolving. Many older languages have stagnated, leading to diminishing communities.
00:18:39.440
I don't want that for the Ruby community; I want it to flourish. Ruby needs to progress to avoid stagnation.
00:18:46.800
We need motivation and a driving force to continue moving forward.
00:18:55.040
The primary motivation behind Ruby 3 is to enhance productivity and enjoyment in programming.
00:19:04.160
We care about programmers and their experiences while using Ruby.
00:19:11.680
The question on your minds might be: when will all of this be available?
00:19:18.800
The short answer is: I don't know.
00:19:26.800
The longer answer suggests that it will take years.
00:19:33.840
We have a lot of work ahead with duck typing, Ruby 3 x 3, guilds, and other features.
00:19:42.560
You may need to wait a couple of years, unfortunately, but we welcome your feedback and contributions.
00:19:54.080
We want your input to help us continue moving forward in the Ruby community.
00:20:01.840
Each Ruby user and developer can contribute to Ruby’s growth.
00:20:10.320
This is perhaps the most important message and motivation behind the Ruby 3 project.
00:20:19.760
Let’s embrace programming in Ruby, enjoy it, and focus on improving our ecosystems.
00:20:28.560
Together, we can strive to become better programmers.
00:20:36.760
This concludes my keynote. Thank you, and happy hacking!
00:20:53.920
Thank you, Matz.
00:20:54.960
[End of transcript]