 Maybe you feel sick of my face. I always feel some kind of conflicting feeling inside of my heart. I'm so happy to see your face smiling, very excited, and excited enough to travel all the way to Cincinnati. And at the same time, as a programmer, I hate to speak before people, but something happened. So I can't help you. Let me. Back in 1993, I started programming. I started developing Ruby just for fun. So I was only a language geek. I just love programming languages. So I love all the programming language. I like Lisp. I like Smalltalk. I like C. I like Pascal. I like C++. And we didn't have PHP yet back then. So I created Ruby just for fun. And it was my pet project. Then something happened. So back then, the Ruby users were me. So then 1995, I put it in on the internet. So far beyond my expectation, I put up a mailing list soon after I released Ruby, the first version, version 0.95. And then soon after I formed the mailing list, so people joined to the mailing list. And in a week or two, we got 200 members. So that's far beyond my expectation. So there are tons of programming languages out there. So most of them are just toy. Yeah, actually, back in 95, so Ruby was a toy. So most of the programming language out there, a toy language, gradually disappeared in the history of the internet. Just because people get sick of seeing new programming language. That was my expectation. So yeah, it was fun to create programming language, design programming language. And I enjoyed implementing the programming language. It satisfied me. So I just put it on the internet out of coincidence. The copying the software on the internet is free. So I learned a lot from free software. So I read through the source code of Emacs. I learned a lot from reading free software source code. So I just put my software back to the internet just in return. But something happened. So people found Ruby on the internet. And actually, they loved it. Kind of funny, though. And then they find Ruby. They loved Ruby. They used Ruby. And they even wrote a book on Ruby. So year 2000, the big expects was out. The famous Dave Thomas found Ruby, and he loved it. He even wrote a book on it. That was far beyond my expectation. So that book was sold, I don't know, to 20,000 copies. And then so maybe I assume maybe half of the people who bought the pick up bus used Ruby, maybe. So the estimated total user back then, year 2000, is 10,000. Then next year, I got a first RubyConf here in the States, in Tampa, Florida. Attendees, so that is something. It was quite small. But considering the size of the conference, the conference this big is so amazing. This year, RubyConf in Cincinnati, I don't know how many? 1,000? 650. A little bit smaller than that last year. OK, total number of that. Right now, I have no way to estimate the number. But a few years ago, Gartner said, OK, we will have the million Ruby users in some years. So I assume, very roughly, we have one million Ruby users out there, all over the world. So the users increased one to one million. That's quite a number. So we have far bigger community. So I think the open source community is kind of a weird thing. So what exactly is a community? So community is not an organization. So it's a kind of group of people. But we don't really have some kind of membership in the community. So once you feel, OK, I feel I'm a member of the Ruby community. So you became a member of the Ruby community. We have no initiation. We have no entrance fee or anything like that. We are just a group of people. And we are no exclusive. So, OK, you are the member of the Ruby community. You cannot use any other programming language. No. Yeah, we don't have that kind of rule. So we are non-exclusive. So as a result, we cannot expect the strong loyalty to the community members. So, OK, I feel I'm a member of the Ruby community today. And maybe I'm a member of the Ruby community. OK, I'm a member of the Go community tomorrow, maybe. Or maybe I'm a member of the Ruby community. And at the same time, I'm a member of the PHP community. And if you feel bored in the Ruby community, you just leave. So we need to attract community to survive. Otherwise, community members will go away. So we eventually disappear in the history of internet. OK, we had one supporter time. We had a language named Ruby, but we don't use anymore. So we will eventually fade away. So I assume that the OSU community is like a shirk. So we have to keep swimming or we die. So in the bigger technology community, so I'm sick of hostile claims like Ruby is dead. Just because Ruby's gems have less Github stars on the Github. Maybe because Ruby doesn't have static typing, because Ruby is no longer shiny languages. Any technology cannot stay shiny for long. And then Ruby has more than 20 years of history. And even Rails has more than 10 years of history. And then more history, and then we have more burden. So we have to do something to survive. Make Ruby great. What shall we do? Rebuilding the language? So other programming languages did similar things. The PHP community once tried a version named PHP 6. What happened? No. So they tried to create a better PHP in the name of the PHP 6. But they failed. They tried too drastic, and then they couldn't make it. So the PHP 6 disappears in the history. And then they tried again the PHP 7, and it worked well. ECMAScripts 4. What happened? No. So they tried to create the better ECMAScript. So they tried hard, and they tried to create great ECMAScript version 4, but they couldn't make it. They retried. They tried to recreate ECMAScript 4, and they failed again. Then they just gave up ECMAScript version 4. And it doesn't mean the failure of the JavaScript, but the only one version, only the failure of the idea approach, the starting from scratch. So that's not good. We have the other examples, like PHP 6, which last year, we finally had PHP 6. But it took 15 years to design and implement the PHP 6. Python 3? Yeah, they are moving towards Python 3. And we had no exception. We had similar things. We had in R1.9. We replaced the virtual machine, and we have many things, including encoding support. But instead, we got huge compatibility gap between R1.8 and R1.9. So it took more than six years to migrate from Ruby R1.8 to Ruby R1.9. So those incompatible changes, because we got Ruby R1.9. We got slightly better Ruby, and then we got faster Ruby, far faster than Ruby R1.9 was far faster than Ruby R1.8. But migration took six plus years. So during those time, so the we core members improved Ruby R1.9, and they leave R1.8 behind, because it's old. But the people kept using R1.8. So no matter how hard we worked on R1.9, people were still using R1.8. Just pity. So we had more than six years of slow progress in the community. This is so bad. I don't want that. So I learned a lesson. We shouldn't just make our language better. It's not enough. Ruby is not the first language out there. Ruby is not the most powerful language. We use Ruby because Ruby is good enough for most of the case for our daily use to create web application or for web admin or something like that. And we use Ruby because Ruby is comfortable to use. So we use Ruby because Ruby is nice. And we love, I hope, we love Ruby's human-centric design. So Ruby is nice. So we are nice. Rinse swan. Being nice could bring power. Be nice. So keeping compatibility is one of them. So compatibility is very important for us, not because we are conservative or not because we are afraid of changes, but because it makes us progress. Think about the 180 era. So we try to make progress in the community, but the people keep using the old version. But if we could keep compatibility, so people use newer version, and the whole community can progress forward with us. So without compatibility, the community keep using old versions that don't pursue beauty of the software. So as a language designer, I want my programming language better. I want my programming language beauty, being beauty. And I want to make programming language better and better and cut out old design. Or maybe I fail sometimes in the design. So I want to cut out old failures in the design. Yeah, that's my desire. But it's a kind of selfish trap of designers. Just because now, so better language satisfies me, a designer. But sometimes the changing, the incompatible change to make language better would bring you, bring users, pain. That's kind of selfish. So the people tend to look toward myself too much. So consider users. Talk with potential users like this. They make a gradual change. Design without our constraint. So the keeping compatibility is kind of design, designing with constraint. Or maybe kind of like a speedrun. They're playing the video game under a very strong constraint. So difficult, but challenging. And we can bring benefit to the users. Being nice include the bring benefit to the users. For example, in Uriban 9, we made some kind of the incompatible change for some reasons. But it was slightly shorter migration time compared to the other programming language. Say, yeah, I don't name the language. But it performs very well. Ruby 1.9 runs several times faster than Ruby 1.8. Just because we had better VM. So I don't consider myself as a super programmer. I'm a language designer. But the hobbyist, so the virtual machine implementer. So the virtual machine we found in Ruby 1.9 was far better than the original version. It runs several times. 50 times maximum faster than the old version. So because of that kind of benefit, so we have the slightly shorter migration time. But even with several times faster performance boosts, so it would take years. So the keeping compatibility is very, very important. So OK. The design example, concurrency. So we have threads in Ruby. Actually, I regret it. Everybody loves threads, right? I hate threads. So in the very early stage of Ruby development, I thought the threading is a good idea. But we had some force assumption. Back then, we had only one core on the computer. So we don't care about the performance. We just, I just considered about a programming model, like a concurrency programming model. So some software could be implemented very cleanly using some kind of concurrency model. So I introduced a thread only for that purpose, not for the performance boost. So by that reason, so the Ruby 1.8, the original version, that used green threads, no native threads. The Ruby 1.9 started to use the native threads. But we had Gil, the global interpreter lock. The threads are very easy. Threads are the easiest way for concurrency. So that is the reason I introduced a thread in Ruby. But to utilize multi-cores, I mean, the real concurrency or parallelism is quite hard. The problem is, so the Ruby threading does not use multi-cores. We have the global interpreter lock. And it wasn't a problem in the past, just because we had only one core for a computer. But it wasn't a problem in the past. But right now, we have multi-cores in the computer. So the real threading in Ruby can easily cause problem, like deadlocks or S-conditions. So if you're a C programmer, it is quite easy to remove Gil from Ruby's C-Ruby source code. But I'm sure your threading program will crash very, very easily. So the shared states cause very hard, non-deterministic bugs very easily. So for that reason, I regret that in threads. But to keep compatibility, I just cannot remove threads from the language. So I don't think we can remove it. Then what? Removing Gil? No, it will crash your program. Adding a new abstraction? Probably, yes. Last year, in this keynote in RubyConf last year, I talked about the streaming model I was experimenting for Ruby 3. I gave it up. After serious consideration, that streaming model was too restrictive. So this year, we present a new model, Gil. And we have a session that talks about the Gil, the new concurrency model. And then it was tomorrow, I guess. OK, let me briefly introduce Gil, rhymes with Gil. It's a membership model. Every object belongs to the Gil. No more objects are not shared between Gil's. You can transfer objects between Gil's. So you can only transfer. So one object belongs to one Gil's at the time. Each Gil's run on an independent thread. So every Gil's run in parallel with Gil. So Gil's wrapped up existing Ruby world. So inside of the Gil's, you can run threads. You can have everything, including threads. So that is introducing the real concurrency, parallelism, into the language, keeping compatibility. So Koichi, who come up with the Gil's idea and the name, will have a session about it tomorrow. So ask him in detail, for detail. OK, example two, the static analysis. In this decade, the static type programming language is pretty popular. TypeScript, Flow, Go, Swift. And then the former two is adding static types to JavaScript, the dynamic types of programming language. And Python and PHP are the type declarations. So explicit type declarations is pretty popular in present time. So we have benefit of static type language. So earlier detection, the better coverage, and then more documentation. So we have this argument, this argument, that argument. Each argument has this type of that type. But this kind of explicit static type has some kind of drawbacks. So we have more code. Just because we had a declaration to the language. So unless flexible. So by adding the type declaration, we often use the benefit of that typing. So that some programming languages, some static type programming language, addressing these drawbacks by adding type inferences. So that you don't have to add a type declaration in your program. Or maybe the structural typing to keep the duck typing kind of similar to duck typing. So everyone knows duck typing, right? No, duck typing is this. No, this is typing back. No, this. This is typing with duck. Yeah, maybe this is duck typing. Anyway, if it works like duck, quack like a duck, we assume it is duck. So we don't care about inheritance. We don't care about structure. We just care about how it behaves. So we can ignore inside detail. So we ask computers with dispatch. Things should just work. That's duck typing. So in that sense, this is a duck because it works like duck. This is a duck, too, because it quacks like a duck. So the interface in Go is kind of similar to duck typing. Like this. So we define the log-dst interface. So every object that comes with the method with write works with the function log. You can put the log output to any object that has the write method. So unlike Java, the class does not have to implement the interface beforehand at the declaration time. But every class, every object that comes with the write method would work for log function. So this is kind of duck typing. This is called structural typing. And then adding structure typing with typing forensic so that enables statically typed, statically typing without declaration, like crystal. You know the crystal language, right? Yeah, crystal is a derivation. Some Ruby-like language, which comes with the static type, the type inference, and then compile to the binary using LLVM. That is quite nice language. We are going to one step further, no declaration at all. Everything in inference, but why no declaration? Because it's against the write. Don't repeat yourself. So it is the principle to avoid redundancy. So I am a true believer of write. So I try to write extremely. So if you can write or execute a program without something, just remove it. So our current Ruby program run without any type declaration, so we just have to remove them. So Ruby program run with a type notation so we don't need them, so we need to remove them. This kind of type system, the structure typing plus inference and no type declaration. So I name it duck inferencing. Duck inferencing is almost equal to structure typing with inferences, like our camel. So duck inferencing is a type system defined by behavior. So behavior is set of methods and argument behaviors, and inferred types do not have names. You don't have to worry about type names. The vague idea in your brain can remain vague. So the naming things is a hard thing, one of the most difficult problems. So you can retrieve a type of an expression by analyzing your code. So the computers or compilers can read your mind, read and understand your expectation to this expression or this object. So you can check compatibility between types. You can check if a type has a method. So the duck inference, that kind of duck inference without any type declaration is not perfect. Don't challenge 100% coverage. But 80% compatibility is far better than 0% right now. It can easily fall back to the dynamic typing right now. So in addition, we will use some kind of ad hoc type information, like a fine type errors from contradiction, like this. This log function has two methods, which we assume the different ducks. And then one duck has a right method. And the other duck can be anything. But the other duck, duck B, is an argument of right. And the all right method in the application takes a string as an argument. So duck B, which is the type of the message, should behave like a string. Or if the variable A takes methods, G solve, slice, and map, but look up in this application, there's no class have G solve, all of the G solve, slice, map. So this is a contradiction. So something should be wrong. So it should be an error. So the static analysis can cause error from that kind of contradiction. Or maybe we can use some kind of runtime type information, especially from tests. So you write tests, right? Yeah. I sometimes regret it. Yeah, we write tests. We encourage you to write tests. If our civilization has progressed enough, so we can communicate to the compiler so that we can tell our intention somehow. So at that time, we will no longer have to write tests. But until then, we write tests. So tests should run without error. So the test runtime information, you can retrieve type information, runtime type information. So why am I so insistent to adding type declaration to the language? Think about the future. So I'm very nearsighted. So if I took my glasses, I cannot see any face. So everything blows. So I can see my hand. So the people tend to look very nearsighted. People tend to be very nearsighted. So at the present technology, adding type declaration is a very reasonable way to gain benefit from static typing. That's behind the reason the PHP, and Python, and the other programming language add optional static typing by adding some type declaration to the language. But think about the far distant future. The programming language evolved to be more and more concise. So very early stage of computers, everything is written in machine language, in assemblies. It was so verbose. And the programming language evolved to become more and more concise. So we can do more things with less code. So adding declaration is the opposite way toward the evolution of programming language. The future is less code, and more communication between man and machine. So seeking expectation in my mind. So typing by class is only an approximation. So typing by class is too restrictive. So the drawbacks is without type declaration, we have less documentation. So we add this kind of stuff in anyway. That is contradiction. So I don't want to specify types for flexibility and to draw. But we need documentation anyway for users. So if we put type information in documentation, like that example before, so it starts typing with enforcement and check. So with a compile time check, it's kind of worse of both worlds. So the compile time type checks of dynamic type language and the verbosity of static type documentation. So the type understanding is a bad idea, I think mixed gradual typing is a bad idea, for Ruby at least. But here's a room for improvement for future Ruby. The dark inference will provide type database for its gems and for your app. You can retrieve a type information from an expression. So you can check compatibility between types, or you can check if a type has a method. So any editor or IDE can access that database so that they can use it for code completion or real time type check. Or you will have sort of documentation from inferences. Or maybe we can work with the documentation. So for the time being, for near future, we write the type info in the documentation anyway. So we can check the documentation type information in static analysis. In that case, we have to carefully avoid nominal type checks. Anyway, that kind of static analysis sounds great, right? But you can't use it now. It's still more concept. So we have a lot of things to do down. We have to work with other tools, like editors, IDs, gems, and profiling tools, and static analysis tools. But I'm sure it will benefit the community. And so that kind of benefit is included in being nice. So we are trying to, we, who design and implement Ruby, trying to make Ruby nicer. That means more powerful Ruby, or more comfortable Ruby, and faster Ruby. Obviously, Ruby community is not just Ruby. Ruby is the language. It's only a component of the Ruby community. So we have Ruby gems, we have frameworks, we have tools, and we have you, people, member of the community. So the gems can be nicer. Your apps can be nicer. So we need your cooperation to become nicer community, stronger together. In summary, be nice. We can be stronger by being nicer. Being nice includes moving forward to survive, keeping compatibility, and making gradual changes, and providing benefits. So moving forward to survive includes adding new progress, or new features, or improvements, or Ruby 3. The Ruby 3 is our goal and our policy. Not because it's easy, but because we need goal, challenging goal. So every goal in Ruby 3, adding new concurrency model, or having some kind of static type analysis, or making three times faster than compared to Ruby 2, every goal is so difficult. It's nearly impossible, I admit. But those challenging goals drive us moving forward. So keeping compatibility is very difficult and challenging task, but we will not break compatibility for no reason. So I don't make a promise. We may break compatibility in the future, but I provide you reason to break compatibility. So not only for my satisfaction, but for your benefit. Gradual changes, we want to throw things away and restarting from scratch. We will never do that again. We will make the gradual changes. It may take longer time, but it works as I believe. The Ruby 3 features will be introduced to Ruby 2x. So you don't have to wait until Ruby 3 a few years later to make Ruby faster or having new features. So providing benefit, the better and faster Ruby 3, we will provide better and faster Ruby 3. And the important things is the bottleneck in the community may not be in Ruby. The gems, frameworks, apps, tools, we have a lot of things to improve. So we need more tools and the contributions to make whole community better. So having better Ruby is not enough. So we have to have better gems. We have to have better frameworks. We have to have better applications. So these principles can be applied to anything, moving forward to survive, keeping compatibility and making gradual changes, and providing benefits. So I encourage you to apply these principles to your work, your gem, your application, your framework, your everything to make Ruby greater again. So we can be stronger together. Very important note. I have no strong opinion against this introduction. One more thing. Yesterday, what day before yesterday, I mean? We had the Ruby 2.4, the preview 3. We have several improvements. Faster hash, integer unification, better Unicode case mapping, often assisted 1.1.0 support. The faster hash, we started to use the open addressing hash, which is far faster than the previous one. This code is contributed by Vladimir Makarov and with help from Yura Sokolov, also known as Fanny Falcom. I don't think they are here. But could you please clap your hands for them? Yeah, thank you. Yeah, integer unification. So in the history of Ruby, we have both fixed nums for small numbers and big nums for big numbers. But it is the kind of the leaky abstraction of the integer implementation. Just because the smaller number can be embedded in the value, so it is classified as a fixed nums. And the bigger numbers are too big to fit in the value, so we have to allocate them into the heaps, so we named the big nums. But that classification is kind of artificial. So after long consideration, we just removed it. So from now on, the integer is an integer, so we have no distinguishing from the Ruby side. So this is kind of incompatibility, but it is benefit of the readable concept of numbers. And we have the better Unicode case mapping. So before 2.4, the case mapping only works for ASCII characters. So the Pokemon, the upcases, the E with the accents remain the small letters. But after 2.4, by upcasing Pokemon, it works as we expected. So we make that kind of improvement here and there for Ruby 2.4. So each year, December 25, we release a new version of Ruby 2. So next Christmas, we will have the new Ruby 2.4 with those improvements and more. And then things will be better each year. And I hope we will have a bright future. That's all, folks. This is my doc, just in case my doc won't envy my cat. Thank you.