 Welcome. I'm Jimmy Shimenty. I work on Iron Ruby, and I will be talking about Iron Ruby. Right away, if you want to, you know, if you've got your laptop built and you want to follow along, there's some links you can go to, go to ironruby.net, you know, download Iron Ruby, and get the source code from the next link, my blog from the next link, and demos from this talk from the last one. So if you want to see the demos before I give them, feel free. Before I begin, though, I should talk about the, what do you call it, I guess the pink elephant in the room, or the 800-pound gorilla, I'm not sure how you phrase it, but so John Lam announced that he left the Iron Ruby team about two or three days ago, and that's not entirely true. He left like eight months ago. He just decided to announce it now. So we've been going strong with him advising. He's still at Microsoft. I still see him all the time. He's just working on a different project. But I figured since he's not here to say goodbye, I would say goodbye for him. So, you know, wave by John. Okay. So let's continue with the talk. So this is kind of the outline of my talk. It's probably going to be completely different, like as far as the times go, but whatever. I'm just going to give a brief overview of what Iron Ruby is, what it's useful for, why a Ruby programmer would care about it. Secondly, I want to talk about Ruby and HTML, actually, in the browser. We'll talk about that when I get there. Next, kind of the bulk of the demo will be all about embedding, basically taking Ruby and using it either as a scripting language or as an extension language to give to users. We don't see a lot of Ruby being used like that. Quite interestingly, it's a big scenario for Iron Ruby. And then I'm going to follow up with the state of Iron Ruby, you know, how we're doing, what the roadmap looks like, kind of stuff like that. All right. So, what's Iron Ruby? 186-compatible implementation. It's got some 1.9 features, like encodings. Other things are hidden behind the 1.9 flag. It's not completed at all, so don't expect it to act like 1.9. But we play around with things in there. It does not support continuations, object space, native extensions, kind of everything you hear from the other implementations. Except for native extensions. We, you know, the other implementations are starting to tackle this. Local call-cc, so local continuations are actually pretty easy to implement when you have a pretty decent interpreter and we do now. So we'll probably have local continuations. And we're considering FFI support because, like, everyone's doing it. But because we can't ignore native extensions, right? So that's just what we don't have, what we do have. You know, we have native threads, we have everything you kind of expect from a compiling or jitting runtime that's underneath Iron Ruby. We run on CLR2 OSP1 that was released in, like, 2005 and above. And we also run on Mono 2. So Mono 2.4 is out and we've run on Mono since. What's also interesting is that there's kind of these browser plugins called Silverlight Moonlight that kind of parallel CLR2 and Moonlight 2. And there are very small subsets of it, which we also run in. So I'm going to, you know, just talk about that a little briefly. And the interesting thing about this, which most people kind of don't think initially, is that we run on a variety of platforms, right? It's not just Windows. It's macOS through Mono. It's Linux through Mono. Solaris, right? SUSE, right? Which is completely different. So because of Mono, we kind of are able to run on a lot of places. And that's why we really care about running on Mono. Because we're not all about just running on Windows, right? Let's look at the room, right? So, you know, I'm serious about this. So like, you know, 10 minutes before, if you saw me working on my Mac, I was sending pictures to myself because I just wanted to prove that it actually did work. You know, it's nothing substantial, right? But I just wanted to have at least have some proof. So it's installing ActiveRecord. This is using RubyGems, and this one's just creating a Rails app. There's really nothing substantial. It's not really proof, but again, I figured I wouldn't just want to wave my hand over it. I'm not going to talk about, you know, how to run Iron Ruby on Mono or on Linux. I kind of covered that in depth at OSCON and wrote a huge blog post about that. So please read that if you want to know about it. So a bulk of this talk is going to be, well, what sets Ruby apart? What sets Iron Ruby apart? What can Iron Ruby do that most other Ruby implementations not can't, but haven't stepped into that domain? Now, this talk will not be about Iron Ruby being a premier Windows implementation, but that's kind of the goal, right? So Ruby itself is unfortunately not the best performance implementation on Windows, right? It's getting better because if we use more modern compilers, we can get closer to what MRI and 1.9 actually perform like on Linux, but it's still unfortunate and there's some features that are missing. You know, you can't, talking to com APIs or Win32 APIs are pretty difficult and we can do a better job with that in Ruby. .NET, right, doesn't exist. You can't have no interop there, so that's kind of where we shine. You can also think about using DirectX libraries actually, you know, writing games in Iron Ruby, how much of it are you really, do you depend on C++ to really get your performance? So, you know, it's things like that. Systems management is another one, you know, writing scripts, right? You know, managing your system like, you know, people have been using Python on Linux and Perl forever and Windows people have Batch, which is, you know, horrible. So, you know, that's another area where we look at. And one of the interesting things is web deployment. So, you know, while we do run Rails and we also run some of the Microsoft web stacks, you know, we don't really focus on doing that. We make sure it runs. We wrote a rack adapter to make sure you can deploy NIS, but, you know, no one's really doing it. The thing that kind of woke me up is that Matt Almanetti is on the Rails core team kind of mailed me and said, hey, look at the wiki for Ruby on Rails. It has 51% of its hits are from Windows. And I was kind of floored by that. I didn't think that was even correct. So, I asked for more stats and I wanted to compare it to Mac, you know, the other platforms. And it was true. Now, I don't know how long we stayed there. I take that with a grain of salt, but, you know, it definitely, there needs to be more focus for the Windows people who use Ruby. It's kind of a whole user base that Ruby doesn't touch. The second one is browser apps. Again, I keep mentioning this. This will be part of the demo and embedding. So, kind of the scenario being a polyglot where your own application has a mixture of languages, where also you're extending this mixture of languages to an end user to let them extend your app with scripts rather than some pre-compiled thing. So, I'm going to talk about those two. The Windows thing, right, you know, again, I know who I'm talking to. I want to talk about things that actually could possibly cross-platform and are a bit more interesting to what Iron Ruby is for kind of everyone rather than just the Windows developers. So, you can't really see that, but let's talk about HTML script tags. So, has anyone heard of this thing called Gestalt? Yeah, so raise your hand if you do. So, Gestalt was kind of cool and it caught me by surprise, not because I was angry that someone beat me to implementing that, but because it was done before and my team was like, oh, we just won't implement it that way. So, it was funny that someone else did it. So, Gestalt basically is Ruby and Python and actually any DLR language. So, DLR is the dynamic language run time. It's kind of like the LLVM of .NET that we build on top of. My team at Microsoft built. So, the script tags in HTML are, you can write Ruby script tags, right? So, if you can't really see that text, Ruby script tag, right? And when you run it, it does what you would expect. Why is this so shitty? When you run it, it does what you expect, right? It says, hello world, I'm going to show you not pulling anything over your eyes, right? Is Ruby code running there, right? Tucking the event. You can't see that one. So, now the unfortunate part of this is this is all possible because of Silverlight, right? So, we're hiding a lot of the gunk that you would normally have to do when you inject a script tag into, or an object tag in your HTML page and hiding it all behind this guy and kind of doing clever things that make you never really know you're writing a Silverlight application, right? It feels like a browser app. Now, for HTML specifically, I personally probably wouldn't even use it because it's like, all right, for some simple HTML manipulation, you can use JavaScript and not depend on a plugin. But if you're going to use Flash for something, or something where you need more than what maybe Canvas provides, this is a no-brainer. I would never use ActionScript as a browser, right? So, the other question is, of course, market penetration, right? So, I'll talk about that in a second. How many people are actually going to have to install your plugin? But this is kind of cool. So, let's just look at some things you can do with it. So, it's not, you know, it's build actual real HTML apps with it. It interrupts with JavaScript very well. So, if I have a network connection, hopefully this will work. This is just an app that does some Twitter or Flickr searching and pulls down images and is looking for the... Oh, I don't have that. Well, that's what happens when an error occurs. And you get a REPL too. Look, there's a REPL in the browser. Holy crap. Anyway, so, it would show you pictures. But that was kind of not the point of all this. Again, I said you wouldn't really want to do HTML apps, but you might want to do, like, you know, cool animations and no vector graphics and stuff like that. And this is completely, you know, possible of doing that. So, it's kind of cool, right? So these two are actually written in Python just because they're written in Python, but it could be in Ruby as well. So, that's really all I want to talk about it. If you want to find out more about it, I don't have network. Gestalt actually released a new version of this today with, you know, a new updated version of Iron Ruby, kind of the Iron Ruby of today and the Iron Python of today. So, you know, if you're interested in it, Google Gestalt and you'll find it. But that was just kind of a side note. I really want to talk about embedding, right? But let's just, for the sake of one more point, Silverlight is a little strange, right? It only runs on Windows and Mac OS and the Moonlight or Nebel had to go off and re-implement it to work on Unix systems. But they're doing pretty well. They're keeping up pretty fast. Silverlight is not stopping it adding features. So Silverlight 4 just came out and it's got some, like, I was pretty amazed at the full trust application part. So basically with the combination of full trust and notifications in Clipboard, you could write up a desktop app with it, right? And have notifications, like, you know, pop up at the bottom or top, have Clipboard access, access to webcam. It's pretty nice, right? So, you know, imagine writing, again, like, you know, something like an Adobe Air app in Ruby, right, for instance. I mean, that's pretty cool. And the kind of other factoid that I liked was it was announced that, like, 45% of the connected Internet that uses Mac OS or Windows has Silverlight as well. And I was blown away by this number. I was like, that's impossible. And then I heard you say it and I was like, that's insane. So the pickup is gaining, right? It was, like, around the Olympics, which last year or so was, like, 8%. So it's definitely growing at a pretty fast clip. So it's a platform to look at, right? And the cool thing is Ruby runs there. So, you know, for Ruby developers, that's interesting, right? I don't like that. So that's all I'm going to talk about Silverlight, though. And the next topic is this embedding thing. One of the biggest scenarios for Iron Ruby, especially when it comes to .NET developers. So it's not like you're taking some crap and wrapping it with crap, right? Like, it's not like you're trying to take, embedding isn't taking, you know, trying to stuff something that doesn't belong in, right? And it's also not painful, right? It's, we've focused a lot on extensibility of Ruby in .NET to be very painless. So let me explain. So there's the DLR, the Dynamic Language Runtime. It's got a bunch of parts. The parts that kind of I deal with on a day-to-day basis are the lower-level compiler stuff, right? You know, I work on Iron Ruby, I very often looking at that compiler code. However, there's also a set of hosting APIs which let any DLR language that speaks the DLR protocol, they can interop with each other, they can interop with .NET code, and from C-sharp or VB or any other, even from Ruby, you can host any of the other languages using the DLR hosting API. And it's very, very terse. I'll show you the code in a bit. Very, very simple code. So the benefit of this, as an app developer, you embed Ruby in your app, you get extensibility with scripts, which is, you know, Mozilla kind of has the whole JavaScript, the plugin, the whole plugin architecture is mainly JavaScript. But being able to control it, like in your app, that took a lot of work for them to embed that. But being able to just make a very simple app and embed your language of choice is amazing for extensibility and for just letting everyone use your app, right? Ruby's awesome in that case because everyone can program in it, right? If you give them just a certain set of things they tell them they can do, they'll do it, right? And they'll contribute to it in some way. They'll make it their own, right? People write functions in Excel, right? 2 plus 2, right? They write that. You know, it could be as easy in Ruby if you were extending your app. But it's also powerful enough just to add features, right? So you could actually build the entire app in this extensibility layer. So you write this little piece that hosts the DLR and then you just do what you want, right? So the cool thing about this is it builds an, you could build an ecosystem, right, for extension developers. You know, I'm preaching to the choir, right? We get extensions, right? But it's something that's completely unheard of in the .NET world. And this is why it's so important to us because, you know, people aren't going to stop using C Sharp in Ruby. So let's still use it and also use Ruby at the same time. And, you know, as a side note, there's more languages other than Ruby, too. Python, Scheme, and Closure actually run on the DLR as well. So, you know, kind of letting people pick the best language for what they're trying to do. So let's fix the worst app ever. I've got this stupid app, right? This is it. You know, imagine someone asked me to build them a paint program. And I was like, okay, here it is, right? It's a canvas and some butt to add a shape. But of course I was stupid, right? And I made it random, right? Like, you know, they can't actually place it. They can only clear it and add more random stuff. You know, that's a pretty crappy app, right? So if I was given this, I would be pretty pissed off. But I was smart, right? And I actually built some extensibility into the application. Right? So there is a window off to the side, which is basically your Ruby interpreter, right? So it acts like a normal Ruby interpreter, where you tell it some math and it gives you the result. It's a little weird that it keeps the text around, right? But that was a design decision. You'll see why. You know, you can keep running it, right? So it's a full Ruby. It's Iron Ruby right there. And you can also access the canvas over there. So this clear button actually does the same as that. Canvas children clear, right? I get through the stuff. So, okay, cool. So, though this app really sucks, I can actually do something with it, right? I can make it better. So, you know, if you're a kind of semi-knowledgeable programmer and you know what the API is, you can kind of look at code and then imagine that you could write stuff. So I have somewhere... Of course, I'm not going to write this all in front of you. So I have, of course, pre-cut snippets. So, you know, we're adding a square, right? Well, it'd be really nice to, like, add, you know, as many as you want, right? So that's cool, right? You can add 100 for all I want. So, you know, this paint program is finally getting a little bit more control. And I really haven't built anything, right? This app is a C-sharp app. It's 100 lines of code. It's really easy to write. And kind of if someone... The whole point is if someone's being really stupid in your, you know, respect, you can take the app and you can extend it, right? And it's pretty easy to do. So let's... Let me just show you what that code looks like. So this is a... This is Visual Studio 2010, the beta that just came out. I'm using it because there's actually some special features that let you interop with dynamic languages in it, Python and Ruby, that are very cool that I'll show you. So... This is not our code. There you go. So... So basically, the DLR hosting API is all revolve around this script runtime guy. That's basically your level of isolation. Everyone see that? Okay, you want it a little bigger? No. Okay. So that's your level of isolation. You create this script runtime, right? And you also create a script scope. And you can imagine that as just a set of variables that your code runs against. So you can take a set of code and run it against one scope, run it against another scope, it could do different things because this property bag, essentially, could have different values in it. The ID fields and the callbacks are kind of irrelevant to the actual workings of the hosting itself. But... that's all you need to do to make an engine. So the reason why there's a different separation between an engine and a runtime is that the runtime is kind of multi-engine. And an engine maps to a language. So in one runtime you can have many languages. The languages can share variables. They can talk to each other because they do share this similar DLR hosting layer. So this engine is basically now Ruby. And anytime we use that engine, it executes Ruby code. So this line here, engine execute, it gets the text of that code box and passes as a second parameter of the scope. It basically says, run this text, eval it against the scope. And then the result of that is going to be returned as just an object, as result. And then the rest of the logic is for doing all the repel stuff. So that's pretty easy. And the only other thing you, of course, would want to take care of when you're running arbitrary code because the engine does fire basically any exception. There's an exception operations service. Now the reason why there's this service is because Ruby has its own exception way to display its exceptions. Python has its own way of displaying exceptions. So this lets us kind of publish language specific hosting things through services. And then you just call format exception, give it the .NET exception, and it's going to spit out and visualize the world as either print a message box or write it to a little error area. So that's pretty simple. The rest might be a little strange, so I should move on and we'll get to the rest of the hosting stuff in a bit. Well, except for this one. You never saw me create the runtime. So this is creating a runtime. And what this does is, like Java and XML, it's the unfortunate world that they live in, there's this whole .NET configuration system which is based on XML. And we let you define one of those files and then say create from configuration, which will go to the configuration file for the application. .NET kind of has a config per app. And it loads the languages. And then the config for this app is for both Ruby and Python. Right? So you can define Ruby. The nice thing about this is, you ship your binaries, you give it to your users. They want to maybe use another DLR language. They just add a line here. It's not like they need to rebuild your app or anything. So that's the benefit. And then really the only other thing I did because I said canvas. How did that canvas get to Ruby? It's because I told Ruby that, or I told the scope that it should have a canvas and that canvas should be the variable canvas. Now, you'll see that there's another kind of almost equivalent looking code grayed out at the bottom that I'll get to later. That's the dynamic features. Right? So unlike this very laid-bound syntax, you actually dot into it and set properties like their fields. And they just magically appear. They're just set. So let's go back to the app, though. So let's just play around with some cool things we can do. Let's run again. Again, I just printed out some squares the last time that was kind of not interesting. So I've got some code that'll render a circle, right? So basically for 360 degrees, but every 10 degrees, I create a rectangle. I set it to be a well-known width and height, but a random brush. So brush.random actually doesn't exist in .NET. This is a Ruby method that I've monkey-patched the .NET method of. So brushes doesn't have random, but I added a Ruby method called randomPLA, which does pick a random brush. And then I add it to the canvas and I set its position by, you know, using sine and cosine. Basically, you know, the whole how you figure out, right, the circumference, right? So that generates a circle. So let's run that. So I didn't actually call anything so large circle. It's the function I defined. And there you go. I've got a circle on it. I generated a black color there, so that wasn't that cool. But, right, so, like, you know, this program wasn't able to do anything before. Now it can actually do something pseudo-interesting. So, I mean, that's the power of scripting, right? That's why this idea of every app should have a console to it, that you can just play around with, right? How many people, you know, play Quake and try to play with, you know, their script stuff. You know, games get this, but for some reason, you know, the cost is too high for, like, you know, business applications or just random stuff you build. That really shouldn't be the case, and that's kind of what we're trying to solve. So let's continue on down this rabbit hole, right? I'm a very, very hungry, angry user. I want more features, right? The awesome thing is, me the developer, I was just very smart about anticipating what they wanted, because, you know, I get what, what I probably should do, and, you know, I know they're going to want animations, right? They're definitely going to want animations. So, if you saw me when I was going through the code, I had these weird timer class, when I stopped the book. I had this timer set here that I created, and where's timer used? I don't know the references. Where's timer used? Right, so I have this lambda that I'm setting to the timer, and this is, if anyone here doesn't know C-Sharp, it's actually not that horrible. Like, I mean, that's a method, that's an event hook. I mean, it looks a lot like blocks, right? That's a lambda expression in C-Sharp. So it's actually not that painful to use C-Sharp. I kind of like it, you know, instead of other languages, right? But, you know, who knows what. But, so for every time the timer is called, if there's this callback function, I'm going to call it. And it happens to be an action, which is basically a lambda in C-Sharp. It's just a lambda that is statically typed to take no arguments and return no arguments. So it takes no arguments, returns a void. That's what an action is. So I've initialized it here, and what am I doing? I'm going to the scope, and I'm asking it for the variable callback. And then I'm setting it to here, and if it is not null, that other case, it's going to run it. It's going to run a method callback at top level. It's going to call back callback every 30 times a second, right? So I can do some animations. So, let's copy that circle again, because let's animate that third circle, the callback, right? So what this callback does is iterates through every child in the canvas, so basically every square, and gets their position, figures out the rise and run, so you can see what you would change their position by, and then calculates the tangent, and figures out each step where they should be. I have to remember all my geometry. And you run this and write it, rotate. So cool. And that's Ruby being called 30 times a second from .NET. And the interesting thing to note here is that usually interrupt boundaries in static and dynamic languages like C and Ruby are very expensive to cross, because they're native, right? And you have to deal with Ruby's VM. In this case, it's the same VM, right? So there's no interrupt boundary. So you can call into Ruby code with a method, and it's nothing more than an interface, because basically all of the DLR is built on top of calling interfaces, because those are fast in .NET, and that's how we do dynamic method dispatch. So it's pretty fast, right? So I don't have a way to stop this, other than setting the callback to nothing. So that should be fine. So I have to iterate through each child here. I really don't like that. That seems like I could do better. Why don't I iterate through each child on the host side and then just call it 30 times a second for each object? That's, I guess, you know, more of the stress test. So that requires more work, right? Because how do I do that? Then I need an interface, right? Again, you're dealing with static languages. I need an interface, and I need to implement this interface so I can call it from the code, right? I can call it from C sharp quickly, and not have to incur any extra overhead of trying to look it up, right? I want it to be a direct interface invocation. So this iObjectUpdater is a very teeny interface, right? It's just an update function, and that's it, right? And that function is going to get called 30 times a second for each object, because if you noticed where we were calling the callback, there's then also this trackerMaker variable, which basically binds to a tracker method and that calls this 30 times a second for each object, right? Because it iterates through it. So while, you know, turning the circle is kind of interesting, let's do something else. Let's make things bounce, because, you know, if we're going to make this into, like, a game or anything interactive, I mean, you need to do bouncing, right? So I'm just going to copy this code. Basically what it does is it makes an object with an x and y velocity, and then every time update is called, target is basically the object you want to move. It's going to figure out if it's off the canvas, and if so, turn it around in that direction. If it's off the canvas in the other direction, turn it around and set its property, right? So it's effectively bouncing off the walls of the canvas. So I'm going to clear this. I'm going to do create myself just random squares, because those seem cool. So when this runs, this tracker method is going to be called for every object, right? So I run it, and they bounce, right? So every time, 30 times a second, I'm making a new Ruby object, random, random, you know, x and y, or for velocity and calculating it. So that's kind of cool. But I've actually done nothing to the app, which you notice, right? I actually haven't added any functionality to the app, right? Because if I go back to how I saw it initially, now I just have squares bouncing around, and if I clear them, you know, nothing happens. Okay, cool. I've really added no buttons. The end user gets no benefit of this, so we should add some buttons. That tracker is still running, right? So as I add things, they start bouncing, right? So that's kind of cool. An interesting side effect of this. You get some interesting effects going on, right? So I can drag things. I can make a clock because, you know, I'm crazy. But let's just add some buttons. You need to define... I'll actually, you know, extend this app, right? Because you can imagine I'm the user. I've now created all this stuff. I actually want to make it real, right? So it might as well extend the interface. So we use this ran squares thing here, which actually doesn't exist, and all that is this guy I didn't define, right? Let's just add that in there. And now I'll get some buttons in various places when I call add rest of buttons, right? So now I've got some extra buttons, right? So I can create that, oh, crash, awesome. Oh, that method didn't exist. That's right. That's very true. We'll continue. So it'll tell me I have an error, but I can keep going, right? But this should work, yeah. If I define large circle, right? So it's actually calling the Ruby code that's being executed. So, anyway, that's kind of cool. The only other thing I wanted to show, is something that Jim DeVille wrote for me last night, because we went to... Anyone else go to the Ruby processing talk that was yesterday? I want to have a couple people. Okay, so this will be new for most people. I won't take credit for it, though. They showed, you know, building up a demo in this library called Ruby Processing, right? Which is using JRuby. It was pretty cool. It was a very compelling demo. And I was like, hey, you know, I could build that in this thing. So, you know, it seemed pretty basic to say, yeah, I could write what they wrote. But I thought it was more interesting if, you know, they would... I would actually use the same API that processing has and just kind of manipulate my app to run that. So let's put this side-by-side and sort of see it. Right, so this was basically the demo that they showed, right? There's some setup method. It does a bunch of things. Some RGB values in an array. These events are significant because they map to, you know, mouse clicks. It's just how the system knows they're there. These are just random functions. And draw is the thing that gets called every tick of the clock, basically, to draw things. And basically what this app does is gets the mouse position and draws a circle there, right? But it only does it when your mouse is down, right? So draw on, right, draw off. So if the mouse is down, it starts going. And then once you release, it restarts again, right? So the counter gets restarted. So let's run this. And I thought this was kind of cool because I took someone else's animation kind of framework and I stuffed it onto mine, which is you have a class. It has this setup and then it has this update method, which is called for every tick of the clock, right? So I just called the draw one. And you set it up by giving it the type that you say is the type I want to work with, right? And I'll instantiate it. So I thought this was pretty cool. So let's do nothing initially, right? But if I start moving, right, it does me good stuff. So again, these random colors. Now I take no credit for the coolness of this, right? Because someone else wrote it. Actually, you know, I just ported it to this thing. But I thought that was pretty cool. It was pretty quick. And then the other thing that I thought would be cool is if I kept doing it, kept going, right? I could actually, you know, I obviously don't clip properly, right? So I could take everything over. It's still kind of performing with like thousands of objects, but the coolness, I was lucky. I left that there. So then I can do canvas children, okay? And then that's this little app, right? So I've actually made this little thing useful with Ruby. And that's kind of cool, right? I wrote a very little piece, and then random Ruby code just makes it work in ways that you can't predict, right? This app didn't touch any C sharp code. It was all Ruby. And that's kind of the power of Iron Ruby and the D a lot. And it's hosting. It's very easy to do. So does the old video support that one? No. So, yes. If you write a C sharp or VB visual studio extension, you can then host the DLR in that and do the same thing, right? So there was a demo that was done at PDC about a year ago where, you know, using Ruby to click on test methods in a C sharp app. And once you click on it, it runs the test. You know, a little, you know, useless demo, but it showed that this thing is awesome. So, yeah, again, it's hostable. And anything that runs on the CLR, you can host the DLR, right? Because the names are confusing. It's really not, it's a runtime, but it's not like a runtime like the CLR is. It does code generation, emitting IL, right? And it's the byte code. It doesn't actually run the byte code, right? So that's that demo. I don't know if I changed that, sure. Actually, I want to show you one more thing. So I have this CLR2 defined, and I can remove that. And now it's using the CLR4 APIs. And these APIs support calling DLR objects directly from C sharp. So in the grayed out code, let's contrast what they were now. So where I had the eye object updater, right, that interface I had to define, I can just call it dynamic now. So dynamic is a keyword in C sharp 4. You're statically typing something to be dynamic, yes. I get the irony. So you're statically typing this thing to be dynamic, which means when I see this type, don't try to, you know, figure out what's going on. Let the method calls happen at runtime, right? And then it acts like a dynamic language as far as method calls, right? So if you notice... So instead of getting this element as an eye object updater, I'm getting it as a tracker of dynamic, right? So now I can do tracker.update, but I don't need to implement that interface. What this is going to do is call the Ruby code directly rather than calling the interface. But since Ruby implemented that interface, it's going to call the Ruby code, right? So rather than having to define an interface, which is pretty static, right? You don't want to define interfaces in dynamic languages. That's kind of against the whole point. You can do this. And the app works exactly the same as it did before. With the same performance interestingly enough, because it's just one slight level of indirection here, because it's basically an interface lookup. And the cool thing is also the... Again, you can dot into things and just set them, right? Window and canvas don't exist, but you're making them exist because you're dotting into them and setting them. It's kind of cool, right? So C-sharp has definitely been influenced by Ruby, right? So kudos to the Ruby team, right? Seriously, to move a ship like that is insane. So it's copying, right? Imitation is the best form of flattery, right? So anyway, let's finish up. All right, so state of Iron Ruby. So it's been a while, right? We announced this thing in 2007, in March, and we've been releasing 0.9.1.2. And we were thinking of releasing 0.9.3, but we kind of looked at our goals and realized what we set out to do, we kind of did for 1.0, right? So we're declaring the next release in RC. So it's funny, all the Ruby implementation, everyone's deciding to have release candidates. So we're declaring it in RC. Basically, that means we want more people to use it. We feel it's ready for more use, right? And amazingly enough, like, you know, in the .NET community, that means something, which is weird. People see you throw a 1.0 on it. RC, oh, it must be better than 0.9.2. You look at the patch between this version and the last version, it's not that much, right? But, you know, we're declaring this in RC because we want to kind of push the adoption more to get more bugs and kind of make it to be a good implementation. So let's talk about performance first. So our goal with performance was to be faster than MRI, definitely. Like, you know, just can't be slower or the same. You have to be faster. And within an order of magnitude to JRuby. So if we're, like, 30% slower than JRuby, okay, fine, you know, we'll be okay with that. We're 90% slower, a whole 100% slower, we should figure out something. So where are we today? So for the Ruby benchmark suite, we're two times faster than MRI on the Ruby installer. Ruby installer is the new build of MRI against Emsys, right? And we're six times faster than the one-click installer. So forever we were benchmarking against that and then we're like, oh, crap, now it's faster. But we were still faster, so it was good. But we're one and a half times slower than JRuby, so not within that threshold. So we definitely need to improve on this by 1.0. And this is just throughput, right? Running code, right? Now, it may be startup too, but, you know, because the Ruby benchmark suite we're hoping from looking at it, it does test only throughput, but it may be some startup things too because throughput startup dynamic language is kind of irrelevant. So as far as startup, just a simple example require active support. We're four times slower than MRI and we're two times slower than JRuby, right? So we know we're going to be slower than MRI. So this is the way it's going to work. But we need to catch up to JRuby. We're actually implementing our own Ruby interpreter to get faster startup. Today we have a DLR interpreter that we convert all of our Ruby trees to DLR trees and then we interpret that. And if we start hitting parts of the code, you know, kind of like tracing, right? If we start hitting things fast enough, we'll start a background thread to jit, a method body or that class. We'll take a piece of code and start jitting it because we know we're hitting that a lot and then we'll actually compile that. So that's how we make the trade on it for startup and throughput. But we definitely need to fix the startup form. So we're not quite there and that's why we're not done yet, right? The reason why it's okay for an RC is because compatibility is definitely very good. Our goal was we need to at least be 90% and any better, great. And we're definitely there. So for Ruby spec itself, we're passing it 92% across the board. You know, like all other languages, we're really good on the language. We kind of suck a little bit more on the core and the library is a little bit easier. But we're above 90, so that's good. Then for libraries itself, just as random examples of things we have in our check-in suite, you know, Ruby Gems is passing, everything's passing above 95%, right? Active Action Pack, Active Support, Ruby Gems. Active Record Test which actually aren't above 90% but that's because of database adapter, you know, bugs, right? So we don't count that because it's not really testing our implementation. It's testing some other, something else. And the other goal is kind of CLR integration, right? Kind of what I was showing you. But kind of the reverse. What I was showing you from typing Ruby code and seeing how it pops out. The goal is you should be able to use a majority of the CLR APIs just from Ruby and not have to write C-sharp. And we fall over in one scenario there which is when you need a static type. .NET attributes are a good example of this. Basically an attribute is a piece of metadata you put on a type that can be reflected over at runtime or at compile time, whatever. And the problem with that is it needs a type to store this information on. We don't guarantee that every Ruby object is a CLR object because that would be very expensive and tedious, right? So it's okay to ship without that, fine with that. So as far as road map, today's the RC. We're going to do more RCs. And, you know, basically if we have no bugs, we'll finish it. But there is more work left to do, especially those 50 bugs. So we should get a work on that. Post 1.0 will kind of resume this cycle and we're also thinking of visual studio integration after that. And it's actually the highest requested feature for visual studio itself. There's no other bug. So this is the highest and the second highest is Iron Python. So, yeah, you know, we're a 7% team. Let's be clear, like, that's ridiculous. Anyway, so we've got a good community. We have a lot of projects that have kind of been popping up and becoming more kind of advanced Iron Ruby. There's other libraries there. And these are just a few, like, things I could fit on the slide. Right? So we're happy with the contributions. We're happy with the community. And we're just, you know, we're continuing to get help to go towards 1.0. So I've gone over a little bit, but any questions? No, we have not tested Braille's 3. So maybe, but I don't know. We test the latest version of Braille's. Thank you.