 So as I said before, I'm Ryan Davis, founder of Seattle RB. We just celebrated our 13-year anniversary last week. Just want to say that this is one of my favorite conferences, and I'm really glad to be back again. Thanks to Mike, all the volunteers, everyone. Can we please give them a round of applause? OK, setting expectations, is it like to do? I hate this, Mike. This is going to kill me. This is a bit of a history talk, which is not really the type of talk I like to give. It has very little code. It's an ideas or a survey talk, more of the things that inspire me and what I want to have in Ruby. And it's 109 slides, or about 3.6 slides per minute. So we should be good to go. More change. I don't know why things reset. OK, so about 900 years ago, this guy named Bernard said the following, we, meaning the moderns, are like dwarves perched upon the shoulders of giants, the ancients. And thus we're able to see and move out, see more and farther than the latter. And this is not at all because of the acuteness of our sight or the stature of our body, but because we are carried aloft and elevated by the magnitude of the giants. And about 500 years later, this jackass simplified it to, if I have seen further, it is by standing on the shoulders of giants. In other words, this is not a new concept at all. Newton was just iterating on the simple idea that every idea we've had builds upon the ideas before them, which begs the question, when we create a language, why do we build it anew more often than not? But what does this have to do with Ruby? Well, everything, right? Otherwise this talk would have been rejected. So while this is probably unnecessary for the audience here, but for the sake and comparison later on, here's a brief summary of Ruby's features. And I just wanted to point out, I really searched for that picture. So Ruby was created by Matts in 1993. It's interpreted, it's a file-based scripting, and I put quotes around that system, and it's purely object-oriented, class-based runtime. It's incredibly complex syntax and semantics, but that is, for a big part, why we love it. It has an extensive class library, numeric tower, et cetera, very rich language, and it was designed and optimized for what Matts calls developer happiness. Here's a basic example for Ruby for comparison later on. This is a simple recursive Fibonacci, and it's optimized for line count, not for readability. Here we can see if self is less than two, return self, otherwise return self-minus one fib plus self-minus two fib. This is killing me. Here we can see the release history of Ruby. And as you can see right here, we have a four-year gap between 1819 and another five years to 2.0. And while I consider Ruby 1.8, the golden age of Ruby, and 1.9 very much not, that gap there is representative of something, and I think that we could have had more out of the language because of it. As far as the language feature goes, not the class library, Ruby 1.0 shipped with almost everything that you use today. Not much has been added since 1.0, almost immediately after its release, we got private and protected. 1.6 introduced class variables, encodings were introduced in 1.9, and then redone in 2.0, and then a bunch of frilly syntactic sugar across 1.9 and up. Nearly everything but the encodings and syntactic sugars predates nearly everyone in this room. Did anyone come in before 1.6? One, ha ha. And I missed 1.6 by about two weeks. If Akira is in the room, I believe he's earlier than 1.6 as well, and that's about it. So Ruby is a fantastic language. I think it could be better. I love the language, but in my opinion, it's not done. It's done a terrific job of taking ideas from languages like small talk, Lisp, and to an extent Pearl. But this is what I wanna have sometime in the future, hopefully the near future. I wanna have more from Lisp and small talk, and I wanna have new stuff from self and Kola, and I wouldn't cry if we de-emphasized Pearl. So here are our giants. We have small talk from Alan Kay, we have self from David Unger, Scheme and Racket by Guy Steele, Gerald Sussman, and Matias Filiacin, and funk slash Kola again from Alan Kay. And to be fair, I by no means imply that any of these people ever worked alone, but they are the figureheads, so to speak, of those projects. So let's start. Let's do some basic introductions first. First up is small talk, and it's one of my first languages that I actually really loved, and I cut my OO teeth on it. Yay, small talk. How many here have coded in small talk in the past? About six, or anyone up top? Nope. So small talk was by Alan Kay and Dan Ingalls at Xerox Park. It was created in 1972, but it wasn't released to the public until 1980. It's bytecode compiled. It's an image-based, not file-based system. Purely object-oriented, class-based runtime. Ruby's runtime is very much based on what small talk provided. It's got an incredibly simple and clean syntax and semantics. There are only six key words and only four precedence levels. It is a fully immersive development environment. It's got a GUI and the development environment is in that GUI. It's very much an incubator for ideas. This is where object orientation really took off. This is where many, if not most of the patterns that we use came from, MVC is one of them, and it was way ahead of its time and in many ways it still is. So here's Fibonacci in small talk. I've grayed out the pseudo syntax that only exists when you write out small talk code to a file, since it's image-based, you normally do that. Otherwise, it's pretty readable to us Rubyists. If you look at the top, we start with the method signature of Fib. That carrot is the return keyword. So otherwise, it's if self is less than two. If that's true, then we return self. If it's false, then we recurse and return the rest of the algorithm. Next up is self, which I'm guessing most of you have never heard of. Has anyone heard of self? Has anyone used self? You and I are gonna hang out later. So a brief summary of self. David Unger and Randall Smith started this in Xerox Park and finished it at Sun in 87 about a year later. It's bytecode compiled. It has a JIT. It is image-based just like small talk and purely object-oriented except that it's classless or what we can now call prototypes. It's got incredibly simple, clean syntax. It's almost exactly the same as small talk in many ways. The killer for me is that the runtime has exactly eight bytecodes. Eight, think about that. Think about how complex these languages are that they can do object orientation and this is doing it in eight bytecodes. It's a fully immersive development environment much like small talks, but much not like small talks. And it is also an incubator for ideas. The Java hotspot was really born here in self. Here we have Fibonacci again. One big difference is that in self, the self keyword is very, very optional. It's optional in small talks sometimes. It's very optional here. So the less than or equal to, the left-hand side is self and that minus two, the left-hand side is self. Makes it a little weird, but once you get used to it, it's actually kind of nice. Otherwise, the syntax is the same as small talks and so I'm not gonna go over it. Okay, so racket is my current non-Ruby love language. It's a type of scheme, so I'll be going over both scheme and racket in this. Scheme was created by Gerald Susman and Guy Steele in 1975. They kept working on it through the early 80s. It was Guy Steele's PhD work. It's a minimal variant of a lexically scoped Lisp. Lisp itself is a functional language that's based on Lisp as the main data type. And innovation galore happened when scheme came around. Tail call optimization, the numeric tower that we're used to, hygienic macros, first-class continuations, et cetera. These were all born and popularized by scheme. In comparison, racket is a maximal scheme. It has a huge, incredibly diverse library that's a lot of fun to play with. They have graphing algorithms, a lot of graphics primitives. You can do all sorts of stuff and it's just, it's a real pleasure to work in. It was created by Mattias Filiacin and the PLT group. Mid-90s, I believe it started. It's bytecode compile, it has a JIT. It is a file-based language. It's mostly functional and it's a multi-language runtime. And it's got a very simple syntax like all Lisp's semantics. It's got rich expressions with extensive macros that are a pleasure to write in, unlike common Lisp's. And it's got things like structural matching that make writing really fun. And much like small talk in self, this does ship with an editor but it's not an immersive system the way small talk is. Like Lisp, there's a lot more parentheses than in other languages. It is prefix notation, so math operators go before the numbers. Otherwise, this really isn't mystifying and it reads pretty much just like what it is. Finally, COLA, or what I call a beautiful tiny kernel. In the theme of this talk, we're coming back around on previous work and we're going to LNK's stuff again. A brief summary of VPRI. Viewpoints Research Institute is LNK's current think tank. They got a five-year NSF grant to work on a project that they called Fonk Foundations of New Computing. The primary project name is steps or steps towards expressive programming systems because all nerds have to have recursive algorithms or recursive acronyms. And basically, this is hard to describe. They want to recompute computing so that whole systems can be stored in one brain and understood by one person again. They want to do from language all the way up to productivity apps in about 20,000 lines of code. So one of the sub-projects of steps is called COLA. It's their underlying runtime and it's an odd statement. It's one incarnation of their underlying runtime and that's an odd statement because VPRI is such a rapidly moving target that they've actually moved on from COLA but this is something I really fell in love with and I think that it needs more eyeballs on it. It's a machine-compiled, file-based system, object-oriented, prototype-based runtime. It's kind of like small talk and kind of like Lisp which we'll see in a bit. And COLA stands for Combined Object Lambda Architecture which I'll describe later. And basically the design goal for COLA is to be the simplest possible language that can be described in itself and bootstrapped. So here's Fibonacci twice. We start with the signature which is on the integer class. It's just called Fib and then whether you have curly braces you go with the Lispy implementation and if you have square braces you go with a small talk implementation and they're exactly the same as the ones I went over before so I won't go over the actual internals. So out of those four systems I wanna go into it's now time to plunder. So, yarr. As I said before, this is where I cut my object-oriented teeth. This is well before OO really caught on so it wasn't so as prevalent as it is now. Seems like every language these days is OO. But when I started there were a few books on it and a couple implementations and I had to figure all that crap out myself. So back in the day, Alan Kay and his team left Xerox Park. Xerox is really good at inventing and really terrible at selling. So they had to cut a bunch of projects and these guys went to Apple to work on what is now called Squeak Small Talk. Squeak, by the way, is open source. It is still worked on today and you can play with it just by downloading it from their website. They decided that they disliked coding in C which is what the runtime was implemented at the time. So they wanted to write in Small Talk so they rewrote Squeak the runtime in Squeak itself in a static analyzable subset of Small Talk. Then they wrote a translator for that subset to C so they could bootstrap and keep going. So this does a couple things. One, it makes the developers happier, obviously. The next thing it does is it lowers the bar for anyone to understand what the runtime is doing because it's all written in the language you're already using to begin with. That increases the contributor base and that increases the work on the runtime itself. Small Talk has a huge class library of the collections or the data structures. There are 66 classes and I couldn't actually show them all because it runs off the end. And of the magnitude classes or the number like classes, there's 32 and then there's just a ton of other stuff. The GUI system and everything else is written in Small Talk so there's tons and tons of code available that you can reuse. If you look at Ruby's core library and you remove all the stupid constants for error number, we have 93 core classes. These two hierarchies already add up to more than that. So there's a lot more available to a Small Talk developer than there is to a Ruby developer. Probably more than anything else though, the developer tools are really what distinguishes Small Talk from everything else. Language supported developer tooling massively increases developer productivity. Small Talk was one of the first GUI systems. It was followed the Xerox Star, another thing that never really sold. Here we can see a workspace which is kind of like a REPL or IRB. It also has a class browser up at the top and there's also a test runner which you can see going green on the array tests. This is the in-memory class browser. It's your normal editing environment. This is where you actually write your code or modify your code. And one of the things you're gonna notice is that it's per method. It's not per file and it's not even per class and that helps you really focus in on what you're working on. So across the top half, there are four panes. The first one is the category browser or what category a particular class is gonna be in. The second pane is the class hierarchy of all the classes that are in that category. Next up is the method categories for the methods that are in that class and finally the methods that are in that method category. So here we're working on the size method for arrayed collection which is one of the abstract collection classes. Finally, or not finally, next up we have the built-in debugger with resumable after modification contexts. One of the big things that small talkers do, they are one of the groups that really popularized unit testing but their unit test system brings up the debugger on a failure. And so what happens is you write a failing test on purpose, you get the failure and the debugger pops up, you go into the code under test in the debugger and you write the code that makes that test pass and hit resume. That test then goes green and you repeat yourself until your system's done. Interest correction facilities like a senders and implementers browser let you look across all your code for a single message. You get to look at all the ways that the method is being used and then you also get to look at all the ways that is being implemented. And this lets you think about refactorings in a cleaner way. And there's a lot more in small talk than I have time to talk about. The first refactoring browser was written in small talk. I really like to bring that up when I'm having typing arguments with people. They'll make the argument that you have to have static types in order to know enough about the language in order to refactor and do other sorts of analysis. And that's simply not true. There are linting tools in small talk that go way beyond syntax and like little heuristic checks that we are used to. And there's a ton of other developer tools. I could do an entire talk on it. In small talks there to really help the developer methods like our inspect really differ. So here we see I'm modifying color to be a little darker than light red and you get back what we would consider the inspect output except that it's code that would reproduce the object in question. And if you copy and paste that back into the REPL and evaluate that, you'll get the same thing back. Versus rubies where if you do the exact equivalent code you're gonna wind up with the default inspect output which starts with the hash, the angle bracket, the class name. For some reason the address is if we care where it is and then the instance variables. And because of virtue of that format this is really just a glorified comment. It's not usable to a developer. Self is different. There's more of a focus on the runtime than language itself because language-wise it's actually very similar to small talk. This was the birthplace of JIT. David Unger's PhD was under the David Patterson, the architecture guy. And his PhD was titled the design and evaluation of a high-performance small talk system. His book on SOAR or small talk on a risk is the best book I have ever read on objective optimization bar none. Self is the reason why Java and JavaScript are fast. Jitting using monomorphic and polymorphic inline caching really means that dynamic languages can be fast. Prototyping or classless OO it really started in self. This wound up influencing JavaScript and languages like IO. And prototyping is really handy. Since 1.9 we've been able to add methods to instances from other classes but we have to write rather ugly code like that in order to do so and as you can see at the bottom it still doesn't really work because you've used a closure to capture that method and clone it into the object. And as a result self was bound to the previous instance. And again a big portion of the system is the developer tools that we lack. Like small talk self has a GUI right out of the box. It's a lot more spartan than small talk but it has an emphasis on the objects themselves that they really find interesting. And here you can see that I'm running through the self tutorial. And so there's a text pane on the right telling me what to do to the objects on the left. And then there's two buttons on the bottom to go to the next step or the previous step of the tutorial. You're sitting on an infinite canvas. And so next step and previous step just move you across the canvas to a different part of the tutorial. And you get to see different instructions and different objects. In self all objects are tangible. You can put your cursor on it. You can move them around. You can touch their slots and you can modify them directly. Makes it easier to inspect, interact with and manipulate them. In the bottom of the box on the left where it says deposit 30 that's an eval box. And in that box self is that object itself. So we're essentially calling self dot deposit 30 if that was Ruby. And it will affect that object directly when you say do it. And if you say get it the result shows up in the GUI as another one of these objects that you can manipulate. The standard tools let you get into and manipulate the objects directly. This is essentially right clicking on this object. And you can see that there are actions to add a slot, add a category, copy a slot, move a slot, et cetera. You can manipulate all of these objects directly. And of course there's a built-in debugger with resumable contexts. It allows you to easily experiment with the code live. Here I'm calling halt in the top box. I'm calling halt on purpose just to show the debugger. But that then allows you to look at the stack, manipulate all the objects in the stack and resume at any time. As I've said before, Racket is my current non-Ruby love. It's incredibly polished. It has a very responsive dev team. Every time I have any sort of problem, I email the list and PhDs just come out of the woodwork to help. I'm not kidding. And it's just plain fun to code in. Racket ships with extensive documentation. Both reference in here, we have some string constructor methods and a newbie friendly guide. You might wanna notice that this is what? It's chapter 19. It's several hundred pages worth if you printed it out. And honestly, as much as we've improved all of our documentation in Ruby, since 1.9, Zach and Eric and a bunch of people have put a lot of commits into fixing up our documentation, Racket's documentation simply puts ours to shame. It's just true. Racket ships with an IDE that's oriented onto beginners. Racket was originally designed to teach high schoolers how to code. But it's actually perfectly useful to advanced developers. There's a REPL integrated and I've got it split to the right right now. And you can even display generated images like the Siprinsky's triangle. Documentation is integrated in the IDE. You can quickly look up any function simply by clicking on the function and popping up that previous little bubble. And when something goes wrong, you have visual stack traces. You can actually see where you are and where you came from and get an idea of how you went wrong just by looking. And Racket has something called structural pattern matching. It's a family of functions all under the match family. And basically what it comes down to is that it's better structural decomposition than Ruby's flat operator and array destructuring assignment. And while those are very handy for us, we work with a lot more than arrays. So we don't have the types of things that they have in Racket and we're held back as a result. Racket has this amazing system where every file starts with this red line. It starts with pound lang and then it declares what language you're actually coding in for that file and they all work together. In this case, we're using the scribble documentation language with the manual sub variant or style to write this document. And this generates scheme code that will then render to PDF or HTML or whatever. And this language system allows new languages to be created and thrive. And it's perfect for the type of DSL work that we like to do. I know it's good for organization, scoping, data hiding, but at the end of the day, Lambda is king. So here's a speed comparison between the Racket code and the Ruby code. They're exactly equivalent to implementations, but the speed difference, well, the units aren't exactly the same. They're night and day difference. And some of that speed is definitely gonna be attributed to the difference in implementation of how scheme runs functions versus how Ruby dispatches methods, but that doesn't account for this level of difference. We need to speed up our method calls by at least four to eight times in order to compete on more than just the Python and Perl playing field that we're currently competing in. And finally, tail call optimization is seriously useful and can help us speed up Ruby. It does make debugging harder, but there are pragmatic solutions to this. So any arguments against that, I think are null and void. Okay, I am behind on time. I'm sorry, I'll try to speed it up. This mic is killing me. So this starts to get hard for me because I may have been off more than I can chew, but I love what these guys are working on so much that it's really hard to ignore. Steps vision of computing is massively powerful. It's also incredibly hard to explain and it feels very hand wavy, and that's because it is. Since VPRA is a rapidly moving target, it's kind of hard to get a snapshot of what it is at any given time and describe it. They wanna make an entire computing system of productivity apps in about 20,000 lines of code and make it so that all that code is understandable by one person. As a comparison, to put to that in a perspective, all those nice shiny Mac laptops out in the audience are running on about 86 million lines of code. Ruby is about 1.2 to 1.3 million lines of code and it's about evenly split between C for the runtime and Ruby code. Steps does massively more than Ruby does and it's about one sixtieth the size. So to start our hand waving, I wanna talk about COLA, which is the combined object Lambda architecture used to find their runtime. The concept's really simple. You use objects as a means of storing things and organizing them and you use lambdas for doing all the stuff. And that makes sense, right? Code needs to go somewhere, objects, and objects need to do things, lambdas, and that makes it a perfect dependency loop. But implementing that loop, the simple object graph looks something like this and it is a bit cut off, but it's understandable. This is the absolute minimal version I could come up with, no optimizations or anything else. But the problem with that is that if anything goes wrong at all, the entire thing is just broken and you get to guess what the problem is because you don't get far enough to actually get any debugging information. They use a language called OMETA to define grammars that can parse both text and object graphs like ASTs. This having many layers of translation as we're describing here, going from the Nile graphic language to the nothing language down to generating x86 code, allows you to have thinner, simpler layers at every step. And more than anything, this is the biggest size multiplier that these guys got out of the system. They also adhere to the idea of sticking to basic axioms, but what the hell does that mean? It means you teach your system geometry instead of defining a huge library to do GUI work. You need to teach it the rules and let it figure it out instead of implementing every combo of everything possible. And in that sense, rules plus geometry outweigh something like GTK's bloatware by a huge margin. And looking at that, you might think I screwed my units up. I didn't. They implemented their graphic system in roughly 250 lines of code. So between using grammars with transformers and sticking to systems of axioms, it makes your runtime much smaller, much more understandable, much more maintainable. And that's something that we should seriously consider because 1.3 million lines of code doesn't fit in anyone's head and 20,000 lines does. And while this section is more than a bit hand-waving, if you want to unhandwave it, please go read the papers that these guys have published. They're absolute gold. In conclusion, I've surveyed a minority of the ideas that I really like. Ruby's at its best when it borrows great ideas from other languages, but it's fallen behind. It's lost its way. It's time for Ruby to step up and do more with these ideas to keep pushing forward and to stand upon the shoulder of giants again. Thank you.