Performance

Opening Keynote: Ruby 3 Today

Opening Keynote: Ruby 3 Today

by Yukihiro "Matz" Matsumoto

In the opening keynote titled "Ruby 3 Today" at EuRuKo 2016, Yukihiro 'Matz' Matsumoto emphasizes the ongoing development and vision behind Ruby 3, highlighting its importance to the Ruby community. The main points discussed in the keynote are:

  • Vision of Ruby 3: Matz presents Ruby 3 as a distant goal that aims for significant improvements while maintaining compatibility with existing versions. He recalls challenges faced during previous transitions and stresses the importance of clear goals for future progress.

  • Performance Goals: The keynote introduces the slogan "Ruby 3 x 3," aiming for Ruby 3 to be three times faster than Ruby 2. Matz explains ongoing optimization efforts in garbage collection and the virtual machine, including the exploration of Just-In-Time (JIT) compilation as a method for achieving this ambitious performance target.

  • Concurrency and the Guild Model: Matz discusses the need for improved concurrency in Ruby, which has historically struggled with the Global Interpreter Lock (GIL) that limits threading capabilities. He introduces the concept of 'Guilds', a new abstraction model for concurrency inspired by the actor model, designed to better utilize multi-core processors while ensuring safety and simplicity in threading.

  • Typing in Ruby: Matz addresses the rising popularity of statically typed languages and their implications for dynamic languages like Ruby. He defends dynamic typing through the philosophy of duck typing, which prioritizes behavior over strict type definitions. The keynote concludes with thoughts on type inference as a potential solution to balance flexibility and error detection in Ruby.

  • Ruby's Future: Matz underlines the urgency for Ruby to evolve to prevent stagnation and promote community involvement. He highlights the need for continuous innovation and contributions from Ruby users to help guide the language's direction. The final takeaway emphasizes the joy of programming in Ruby and the collaborative efforts required to enhance its ecosystem.

Overall, the keynote serves as an optimistic outlook on Ruby's future while inviting community support and engagement to realize the potential of Ruby 3.

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]