Stan Lo

What would your own version of Ruby look like?

I believe most of us love Ruby, but I also believe most of us don't think Ruby is perfect. So what'd your own version of Ruby look like if you can create one?

As some of you may know, I created a language called Goby about a year ago. It's largely inspired by Ruby, and looks very similar to it. But it also have some design choices different than Ruby or have some unique features that Ruby doesn't have.

In this talk I'm going to discuss some important things we should focus on when designing a language. And I will al
so share the design choices made when developing Goby, as well as the philosophy behind these choices.

RubyKaigi 2018 https://rubykaigi.org/2018/presentations/_st0012

RubyKaigi 2018

00:00:00.900 Hello everyone. My topic for my talk today is about what your own version of Ruby would look like, and my name is Stan. I'm a Taiwanese engineer currently working remotely for an Irish company called Ticket Off.
00:00:07.140 I want to give this talk because I have my own version of Ruby, and some of you might have heard of it. It is called Goby. Today, I want to share some of my vision for Goby and how it differs from Ruby.
00:00:13.590 This is today’s outline. I will first introduce my language Goby, and then I will share some of the thoughts on what it feels like to have my own programming language. Finally, I will discuss my vision for Goby and my plans to achieve it.
00:00:21.210 Goby is an object-oriented scripting language. Its main goal is largely inspired by Ruby, from syntax to internal designs. It is currently over a year old, and we just released version 0.1 in March.
00:00:35.130 We have already equipped Goby with some required libraries for writing web applications, so it can now be used to create simple apps. I believe some of you might be curious about what it feels like to have my own language.
00:00:48.210 In short, it is a tremendous learning opportunity. First, I gained a deeper understanding of at least two programming languages: the target language Ruby and the host language Go.
00:00:56.070 As I mentioned earlier, Goby is inspired by Ruby. So, in developing Goby, I spent a lot of time studying how Ruby works, including its syntax and instruction sets. These are aspects that we don't usually think about when developing web applications.
00:01:08.939 I also needed to learn about Go, not just how to use it, but also how to implement its features. In programming languages, various aspects can be executed significantly more often than others, so we need to focus on performance in these key areas.
00:01:20.659 For example, this month, we improved our overall performance by 10% simply by changing about ten lines of code.
00:01:30.030 Writing Goby has also enhanced my knowledge of computer science. For example, I had to learn how to write a parser since we didn't use a parser generator; we created our own parser. I also studied exception handling, as we are trying to design one for Goby.
00:01:43.229 In designing a new programming language, I think studying concurrency and safety is crucial. I took some related courses on this topic. My main job involves developing web applications, so I have a lot of tasks that align with this goal.
00:01:55.560 Writing Goby keeps me motivated amidst the mundane tasks. Besides writing code, I have other responsibilities, like managing documentation and preparing talks. While these tasks can be overwhelming and stressful, I find they are more rewarding than burdensome.
00:02:10.200 Now, let's talk about my vision for Goby. There are three key aspects I envision for it. First, it should maximize productivity for its users. Second, I want it to offer constant concurrency support because it is written in Go.
00:02:24.230 Lastly, I hope Goby can be extended with existing resources, allowing developers to utilize current libraries instead of building everything from scratch.
00:02:33.750 These three aspects can be simplified into three core values: productivity, concurrency, and extensibility. However, since Goby has only been around for a year, we haven't collected sufficient statistics on its concurrency performance.
00:02:47.130 Thus, this talk won't focus on concurrency optimization, but if you're interested, feel free to find me after this talk and I can share some examples.
00:02:54.820 Today, I will mainly focus on our plans to enhance Goby's productivity. Before that, let me give a short introduction on how we plan to improve its extensibility.
00:03:01.750 I think most of us would agree that Ruby has a mature community with a lot of exciting resources. This chart from GitHub shows the number of repositories for various languages. As you can see, Ruby has around 870,000 repositories, while Go has about 285,000, totaling over one million repositories.
00:03:12.820 I believe it would be great if we could utilize these resources easily. Goby has two approaches to achieve this goal. The first one is a plugin library, and the second is a Ruby-compatible syntax and similar internal design.
00:03:20.750 Let’s first discuss the plugin library. It is based on Go's plugin pure mode and allows users to compile and link Go packages at runtime. This way, we can use packages with 100% Goby code, and it is very straightforward.
00:03:32.600 For example, we can ping a PostgreSQL database using only Go packages. Here’s how you can generate a plugin.
00:03:39.500 You can see that we can import packages and use functions, creating first-class objects and calling methods seamlessly.
00:03:47.500 This feature is already supported on macOS and Linux. Being able to use Go libraries is crucial for Goby since Go is one of the most popular languages for writing high-traffic web applications.
00:03:59.500 With Goby, you will be able to write high-traffic applications using Ruby-like syntax. Next, let's discuss Ruby-compatible syntax and internal design.
00:04:08.330 Here is a piece of source code from our testing framework, and I believe you can read and understand each line easily. As mentioned earlier, we have Ruby-compatible syntax.
00:04:18.180 From my experience with Ruby, about 80% of our code involves defining classes and modules or coding methods. Thus, if we can provide the same syntax and mechanism, users can easily import many Ruby gems into Goby with minimal modifications.
00:04:29.800 However, during the last time I gave this talk, I received questions regarding why we cannot directly run Ruby gems in Goby. The reason is that Ruby is an interpreted language.
00:04:39.750 To use a pure Ruby gem, we would need to support many features, from syntax to functional levels. However, we do not aim to become just another Ruby implementation.
00:04:50.320 We will explore new methodologies and potentially drop some features. Thus, we do not plan to support all Ruby features, and even if we wanted to support every one of them, we would face the challenge of method set defaults.
00:05:06.380 This means that while it is easy to replicate 80% of Ruby's features, it becomes significantly harder to replicate the remaining 20%. Nevertheless, to help users share their Goby libraries, we will introduce a library management tool in the summer, integrating a dependency management tool in the future.
00:05:17.560 Let’s move on to the main topic: our features and plans to make Goby more productive. A productive language, for me, must excel in three areas: readability, consistency, and predictability.
00:05:27.810 I will explain how we improve these aspects. First, readability refers to how semantically clear programming languages are. I believe Ruby’s syntax is perfectly symmetrical, which is why Goby has Ruby-compatible syntax.
00:05:36.160 We are not planning to change that. The next aspect is consistency, meaning how many ways one programmer can write the same program.
00:05:46.600 In Ruby, there are usually several ways because it is a very flexible language. However, for Goby, I want it to be less flexible, as I am tired of so-called best practices and style guides.
00:05:57.120 While it takes time for the community to create such guides, individual developers also spend time adapting to them. Most importantly, developers, including myself, still find themselves adjusting formatting and settings for each project.
00:06:06.210 As a result, there is still no universal coding standard. Let’s take a look at two Ruby best practice examples sourced from a well-known repository, the Ruby Style Guide.
00:06:18.750 The first example suggests that we should avoid using the ‘unless’ keyword in certain conditions, and similarly, we shouldn't use ‘then’ for 'if' statements.
00:06:29.840 In an ideal world, these two examples shouldn't exist in a style guide at all, as they could be eliminated at the language level in the first place.
00:06:39.270 To maintain consistency in Goby, the first measure is to have strict syntax rules. In Goby, we will stick to using `if` statements — there will be no ‘unless’ keyword.
00:06:49.900 Every developer will write conditional statements in one way.
00:06:54.330 The second aspect is the order of parameters. Let me explain why the order of parameters is significant. This is also derived from the Ruby Style Guide.
00:07:05.560 As shown in previous examples, failing to define parameters in the correct order can lead to unexpected behavior.
00:07:16.900 In Goby, when defining method parameters, you’ll need to specify regular parameters first, followed by the optional parameters with default values, and lastly, the keyword parameters.
00:07:28.100 This practice keeps method definitions consistent and prevents unexpected behaviors from arising.
00:07:37.600 These two examples illustrate how we will enforce syntax rules, and we will choose a strict approach. We will also provide official coding guidelines that will cover coding style and best practices.
00:07:46.800 Once the community establishes these standards, we will provide an official formatter. We understand that programmers prefer simplicity, so we want them to format their code with a single command.
00:07:57.400 The most important goal is for all users to achieve the same result, which is to eliminate global configuration settings and reduce discussions about coding styles.
00:08:05.960 Finally, we will strive to make Goby highly predictable. I want Goby to adhere to the principle of least astonishment, which suggests that a system should behave in a way that users expect.
00:08:20.560 Users should not be surprised by any behavior within the language. In Ruby, some features, like monkey patching or method missing, can sometimes lead to unpredictable behavior.
00:08:31.650 This is why we are considering changing or omitting certain Ruby features in Goby. Let’s discuss our first approach to enhancing Goby’s predictability: limiting the impact of method missing.
00:08:41.500 In fact, Ruby already has strategies in place to make some of its features more predictable, such as refinements. Let me first give you a brief demonstration of this.
00:08:52.050 Here’s a piece of sample code where we extend a class using the refine keyword. To activate this, you need to use the using keyword with the module that contains the refined methods.
00:09:03.270 If your method definitions include conflicts and you call a method before using them with the module, an error will be raised. However, after using the refinement module, you can utilize the refined methods.
00:09:15.600 This introductory feature of refinements helps in limiting the impact of monkey patching by allowing a class to be modified locally. Similar to this, we want to approach method missing in Goby.
00:09:29.300 In Goby, method missing will not be inheritable by default, which means that unless explicitly stated, you won't receive any unexpected behavior from the inheritance chain.
00:09:40.500 This structure will help prevent confusion from unexpected method missing behavior, especially from ancestor classes or included modules.
00:09:54.900 However, I understand that sometimes inheritance of method missing can be necessary. For example, if you have an abstract class, you can explicitly enable it in any subclass.
00:10:08.200 By making method missing inheritable only when specified, it becomes clear which classes will trigger unexpected results just by examining the definition.
00:10:18.300 Next, let's talk about exception handling. This is a topic I recently found very interesting and vital for language design. Exception handling interrupts normal execution flow to transfer control to a designated handler.
00:10:29.600 In Goby, our approach is to limit support for traditional exception handling mechanisms. This decision is not due to performance concerns but rather stems from our belief that exception handling reduces predictability.
00:10:40.400 Let me clarify with an example. Imagine a method in a class that calls another method from a library, and that method has the possibility of raising an exception.
00:10:54.820 If the method from the app also raises an exception, this creates confusion regarding the flow of execution, making it difficult to predict which method's behavior will take precedence.
00:11:07.000 As shown in this diagram, the flow of exceptions can lead to unexpected behavior, complicating the program execution drastically.
00:11:17.320 To address this, we propose treating errors like objects, akin to how they are handled in Go. In Goby, errors will be passed as normal objects, allowing developers to choose to deal with them immediately or defer handling.
00:11:29.440 This method allows for clearer control and minimizes unexpected code flow. As such, we aim to introduce a new class, ‘Result,’ that captures error messages and allows composition of different conditions.
00:11:38.600 This new class is still a work in progress; however, we are eager to receive feedback and will share results as we continue to develop it.
00:11:50.640 To summarize our plans, we aim to give Goby strict syntax rules and create official coding guidelines. This will facilitate easier collaboration among developers and reduce disputes over coding styles.
00:12:03.000 Furthermore, we want to establish default non-inheritance for method missing to limit its impact while also providing a path for optional inheritance.
00:12:11.800 Finally, we are focused on developing a ‘Result’ class to efficiently handle errors and avoid checking for errors through traditional conditionals like if statements.
00:12:21.650 In conclusion, here are some helpful resources that I utilized while creating Goby. The first resource is 'Write an Interpreter in Go,' a book that guides you on writing a functioning interpreter in Go.
00:12:35.470 The second is the ‘Build a Computer from Scratch’ course, which takes you on a journey of creating a computer from a basic virtual machine to an operating system.
00:12:46.120 Lastly, you might already be familiar with ‘Ruby Under a Microscope,’ which provides insights into how Ruby internally operates.
00:12:58.760 We are always looking for more contributors for Goby. Currently, we have four to six regular contributors along with about 40 to 50 people engaged in our Slack channel.
00:13:10.470 Discussions about programming languages and features occur regularly, and I would like to take a moment to share our contact information.
00:13:18.910 Thank you for your attention. Is there any questions?
00:13:28.090 Recently, many languages have developed their own tools and feature sets. What do you think about this? Are there any plans to develop similar tools for Goby?
00:13:38.960 Yes, we are indeed looking to build a code formatter. However, we need to establish our style guidelines first.
00:13:45.870 Before that, we need a sufficient user base to understand community practices better.
00:13:55.080 Thank you for your question. You mentioned your further goals regarding Goby and the recent developments in your web applications. If someone wanted to create an application, would Goby support it in other ways?
00:14:07.320 If I wanted to build an application solely using Goby, would that be feasible, or would you recommend using existing languages or resources?
00:14:16.300 You can indeed use Goby alongside other languages and libraries. If you prefer to work strictly in Goby, that is feasible too.
00:14:25.580 As for further plans to integrate APIs and libraries, we welcome any discussions on that topic after this session.
00:14:34.950 I apologize; I am having difficulty following along in English. Thank you for your talk. Can Goby utilize resources from Ruby or Go, such as Ruby gems?
00:14:47.060 Currently, since Ruby is an interpreted language, we need to interpret Ruby source code to implement its features. Thus, we can mostly utilize only very small Ruby gems directly.
00:15:04.650 Most Ruby gems require modifications before they can work with Goby because we need to adjust for differences in language syntax.
00:15:14.130 This allows us to link properly with Go packages and resources, and we have plans to fully support Ruby extensions in the future as Goby matures.
00:15:21.570 However, integrating with existing Ruby gems often requires some code adjustments to work effectively with Goby.
00:15:30.440 Thank you for your engaging talk, and I think it’s very inspiring. There is one part I didn’t fully understand — could you clarify Goby's concurrency model?
00:15:38.930 Yes, Goby’s concurrency model is built upon Go's model. We utilize goroutines for concurrent operations, and we communicate using channels.
00:15:49.160 In Goby, channels do not enforce type constraints, allowing flexibility in object types being exchanged between goroutines.
00:16:01.220 This approach provides Goby with a shameless concurrency model, allowing for effective communication and collaboration among concurrent processes.
00:16:10.540 Implementing this concurrency model took four years of development, and I would be happy to delve deeper into it with you.
00:16:16.580 Thank you once again for your attention.