 I'm going to talk a little bit about some related projects that I've been working on, related language projects that I've kind of termed the Ruby mutants. And you may see things that horrify you here, but that's OK. That's good. It's a learning experience that we're going to go through together. OK, so there's contact information, working at Engine Yard, Yay, JVM enthusiast, et cetera. How many people are in the what I would call Java bigots category? Go ahead, you're going to admit it, admit it. All right, all right. At least I know what I'm dealing with here. OK, so you all know what JRuby is, Ruby for the JVM or a different VM for Ruby. Callback and forth between Java and Ruby and a pretty good implementation of Ruby, I think. It's kind of been a labor of love over all these years. And we've managed to have a lot of contributors on and off, as open source projects do. But there's kind of a problem with JRuby. JRuby has been termed by people who shall remain nameless as Ruby for Java developers, which of course is totally false. It's just a Ruby implementation. You don't have to write Java. It's just co-opting all of the infrastructure and VM of the Java platform to make Ruby better and to give more opportunities for Ruby people to do Ruby things. It's Ruby, Ruby, Ruby, Ruby. So to get the Java thing out of here. But there's a problem. Yeah, a little lower. I'll put this up here. Okay, that sounds good. Two. Okay, good. So it is a mostly Java code base and actually quite a bit of Java as we've evolved and optimized things and implemented more bits and pieces of missing functionality. And unfortunately Java seems to terrify Ruby folks. One of the tweets that I saw yesterday was that JRuby is still too much Java. Even though you don't have to write any Java and you never see any Java. I don't think we even had any Java in the presentation but somehow zero was too much Java. Just because there's a J in it somewhere and it happens to run nearby Java stuff. But to be honest, Java is kind of a verbose in elegant language. It's a systems programming language with a lot of ceremony that goes along with it. And the evolution of Java tends to be moving a little bit slowly, a little bit too slowly. There are some nice features coming in Java 7 which maybe by 2015 we'll have Java 7 and we can all start to use it. But that is not available right now and so we need another way to move things fast. So can we use a different language to implement JRuby? Well, why not some of these other languages? We've heard in the previous talk here about Scala. There's Clojure, which we heard about earlier today. There's Groovy, there's Jython. There's lots of other different languages for the JVM. Why not choose one of these? They're nicer, cleaner. Some of them are still pretty fast. Do they fit the requirements, however, of what language I might wanna implement JRuby in or what you might wanna use to implement something on the JVM or to implement JRuby? So here's my list of what I want out of the next language or another language. I want it to be as fast as Java or as fast as whatever the native language would be. I want it to have no runtime library. So when I compile the code, I want that to be it. I don't wanna have to drag along a four or five or 10 or 20 meg runtime library everywhere that I ship my code. And using a feature of my language should not automatically introduce a bunch of runtime dependencies. That seems fairly obvious, right? I want something that's like Java C. You replace it, you get class files out of it, and you're done. I want it to be easily extensible so that as things evolve, as the language evolves, as people find new uses for it, it's easy to add new features and to modify the language in new ways. Similar to how Ruby is very flexible and really extensible. I want to have a nice, beautiful, clean syntax, obviously. And I want it to at least feel dynamic if it isn't entirely dynamic. So that's a pretty tough list of things to meet, but I think that the language that I'm playing with, language I've been working on called Doobie, maybe may fill all of these requirements. So Doobie is a statically typed Ruby-like language. It is not Ruby. It's made from Ruby, so it tastes like Ruby, but it is not Ruby. It has Ruby syntax, and then it has pluggable transforms, macros, it has pluggable static type system with local type inference to reduce the amount of declarations you do. So like Scala, you maybe only have to declare types once or twice. Pluggable backends, so I'm going to be talking mostly about the JVM backend, but you could certainly plug in other backends and use lots of different backend runtimes. All right, so quick little syntax tour. You all know Ruby, I assume. Most of the structures of Doobie are basically Ruby. It actually uses Ruby's syntax and then transforms it into other things. So classes and literals, flow control, methods are basically the same, except that you'll have some type declarations I'll show in a moment. For the JVM backend, you have things like imports and package and implements and whatnot. Those are not really part of the language, they're just plug-ins for the Doobie compiler. New and initialized for object construction, which again is pluggable, you can have them be something else. You can have them work a different way. Method overloading, interface implementation, et cetera. So here's the canonical example of the stupid Ruby code to show on a slide. The dumb fib example. So here's the Ruby code for it, as we all know. And there is what it would be in Doobie. So it's essentially the same code, but it has a little type declaration on the method. And that's all that you actually have to do to turn the Ruby code into the Doobie code. And now if we explore this a little bit more in depth and see what actually comes out of this for the JVM backend, notice we've got, we've got declare paramount types where circular type references are okay. And with all the local and type inference stuff, it will also infer the return type out of this. So you don't have to necessarily return type if it's obvious from the code, if it's statically determinable. So here's what that outputs as far as the class goes. Normal Java class with a fib method takes an int and returns an int, so it figures out the int stuff. Here is the byte code. You didn't expect to see JVM byte code today, but there it is. And this is almost identical to what you would get if you wrote this in Java and compiled it with Java C, except that it's basically like Ruby code with just the type declaration. And it runs about as fast as Java code does. Actually it runs exactly as fast as Java code does. More recently, Ryan Brown from Google implemented a Java back end as well. So an example of how there can be lots of different pluggable back ends for the compiler, this one actually just outputs Java source. And so here we have essentially the same fib function implemented in Java code, but spat out of the back of the doobie compiler. Okay, so what's actually happening here? What this does is it takes the Ruby code with minor modifications to the parser to support the type annotations, and it transforms that into, well, it does the parsing into a Ruby AST that has some type nodes in very key places. From there, from there it goes through the doobie transformer. Now anything that's in red here is actually implemented in Ruby. So we get the Ruby code, we got the Ruby AST stuff, and now the transformer and the plug-ins that go into it walk through the Ruby code and do various minor transformations to adjust things. So for example, if there's a plug-in for import, it'll turn import into the appropriate node, appropriate doobie AST node, for doing a Java type import, et cetera. So then out of that we get an untyped doobie AST. So that's kind of the first real phase of what doobie's doing. With the untyped doobie AST, then you can pass it through the next phase, the type inferrer, which is probably the dumbest possible type inferrer, but it is written in Ruby and anybody can play with it, anybody's welcome to improve it. I just whipped it out in like a weekend and it sort of works reasonably well. So the type inferrer also can have plug-ins, so plug-ins for JVM types, plug-ins for Objective C types, or whatever your back-end is, you would plug in little bits and pieces that know how to do the typing information for that platform. And what you get then as a result is a fully typed doobie AST. Once you have the fully typed doobie AST, you can pass it through the last phase, the compile phase that actually generates back-end code. And now there's both red and purple on this, it's kind of difficult to see with the lights, if someone could maybe bring those lights down over there. So mostly the compiler is written in Ruby, but depending on whatever back-end it is, you may have a JVM, a Java library that outputs bytecode, you may have LLVM that does native code, et cetera. But mostly written in Ruby, and most of the plug-in stuff is all written in Ruby as well, and I'll show a little bit of that later. And then what the result is is you get native code, platform native code, that's great actually. Stay right there, it won't work so well for the video though, right? Yeah, well, that's tough. Do we have another? I will continue, and I'll let the gentleman deal with lighting issues. Okay, so, and I'll turn my keyboard light on. Okay, so this is all written in Ruby. Now, I'm gonna show the examples now, I wanted to do a little sidebar here about byte script. Byte script is a little library that I've written, there we go, get some light, just don't look directly at it. So byte script is a little Ruby library I've written to wrap the ASM Java library. ASM is basically just a bytecode library. It has a reasonably good Java API, but I made a nice DSL to wrap it and you'll see a little bit of examples of that once I show you the code. Okay, let's do it live. All right, so first off, I'm just gonna show the basic stuff we've got bin, doobie, and there's also doobie c for doing ahead of time compilation and doobie p for outputting, basically show you what the AST actually looks like that it's gonna produce. So most of this is gonna look pretty much like Ruby. We run this, and this is actually, it's starting up and it runs with JRuby, so the startup time is mostly just the JRuby bit loading up. If you can pre-compile this and run it as a Java class file, it's as fast as loading a Java class file. So there, Puts one and all the basic stuff works. And this is all still just statically typed code. It's figuring out that one is a fixed num or an int or a long or whatever the platform uses. Puts here is actually defined as a keyword in this particular set of plugins that I'm running with. So Puts becomes a Java based system out print line call and it then passes the one right into that. So let's, we'll dig a little bit deeper and see what this is doing behind the scenes. So bin do be, and I'll do it more verbose now. So let's do one plus one again. Okay, so we'll get the verbose output from the various compiling phases. And what you'll see here, first off in the AST it's resolving that we've got two fixed nums, right? And now we've determined that there's a plus method between them, a plus operation. And since we know that fixed nums are going to resolve into int types, we're trying to find a plus method that is called on an int and receives an int, okay? And we don't have that in the base set of do be stuff. That's something that you would have to define on a back end specific basis. So it defers doing any of the type inference logic for that. And then as a result it can't determine what the result of the whole script would be. So it defers that as well. Then it dives into the type inference cycle here. The first cycle, okay, again, I still don't know what plus with an int actually is supposed to do. So it pulls in one of the plug-ins for do be, which is the Java back end. Now the Java back end actually knows that when I have an int on the left side and an int on the right side, the plus operation is going to produce another int. And so now we've resolved the plus for the two, for the one plus one. That call has been resolved. We've seen that the call for plus here does an int type. Since that's at the bottom of the script, the type for the whole script is also an int type. And finally we've resolved all types. Yes, Ola. You said that the type resolution for plus will be a type in what will happen to overflow. But it does exactly what you define the plug-in to do. And in the JBM case, the overflow is just it overflows to a negative int. It's exactly like a regular int addition. Yeah, as long as that. No, it doesn't do that, it doesn't do that. But it's something that could be added. And so we look at the overflow value and change what resulting type. So again, this is whatever you want to make it for a given back end, for a given run time. Mostly I'm interested in it to be a better Java language. So it does what Java does. Okay, so what's another good example here? We'll talk a little bit about performance. One of the things that I wanted out of this language is that the performance is as good as Java with no exceptions. And we'll do a little example here. I have some of the code up. Let's take a look at, here is the little Mandelbrot fractal script. We did the fractal generation as part of the JRuby talk. And this is one that a few people have batted back and forth and said, oh, look how fast I run the fractal benchmark. And look how I fast I run the fractal benchmark. You know, meaningless competition in this case. But it's kind of interesting to see what the difference is between the fractal benchmark that's written in Ruby and what does it look like when you have the doobie version. So here is the Ruby code. Doing the whole fractal thing and da-da-da-da. I am using the Java system current time milliseconds just to keep the code a little bit more similar. But this is basically Ruby code. So let's run this with JRuby. Fractal.rb. And we do pretty well on this. Oh, here, you gotta pull in Java libraries. We do pretty well on this. We haven't done a whole lot of performance work recently, but we run faster than most of the main production implementations of Ruby at this point. I think I've got this setup to run something like 10 times. Yeah, 10 times and it'll run. And it should settle in around 1.4, 1.5 seconds. And that's pretty good. That's faster than most of the other Ruby implementations at this point. Now, if we look at the doobie code, let's go back here. And actually, maybe this is easier. Let's do diff fractal.rb. Fractal.doobie. That's it. These are the only changes that I actually had to make to this script to turn it into doobie code that is statically typed to use, in this case, doubles. And the 2s stuff is the requirement of Ruby when you do an addition of a string and something that's not a string, you have to turn it into a string yourself. And that's about it. Now let's run the doobie version. This will be much quicker. Okay. So 0.33, right? 0.033. Now, of course, this isn't really a fair test. This is using Java primitive values, and so it's using all the lowest possible level x86 operations to do all of this stuff once it actually jits down and compiles to the native platform. But it gives you an idea of how much expressivity you can still get with a little bit of clean local type inference and some of the static typing stuff. Let's go back here and see another example. This is a more complex example of using, actually calling out to Java libraries. So here you see that we've got the imports up at the top. And again, the import is just a plug-in that you could remove or not have. You'd have whatever the equivalent is for your backend. Import a couple of classes here. And then the rest of this is pretty much exactly what the code would be in JRuby. We're creating a new frame, setting the size, making it visible, adding a button. Here we're gonna implement an action listener. The only difference here is that we do include action listener if we were doing this with JRuby. Implements is a little bit more in line with what Java folks would expect. I've got our action performed. This is actually a cast here to a J button so that we can get the set text and call the set text thing to set the text of the button. And I could run this, but it's not a particularly exciting demo. But it shows that really there's almost no types. There are no types declared in this at all. And how is that possible? We do have one method down here. Well, in this case, if you're implementing an interface and you're implementing the method, in this case action performed, and it sees that the interface has an action performed, it knows what the type is for that argument and it just pulls it in. You can still go and declare it if you don't wanna use the one from the superclass or from the interface, but it will do it for you in this case. So it knows that it's going to be a Java AWT event object and that's what the type of it is. So a little bit more into the back-end code. We'll walk through a simple case, a simple case of turning the Ruby syntax into whatever the back-end wants to be. So this is actually in the first, I guess it would be the second phase, this is the transformation of a Ruby array node, which is coming out of the JRuby partner, into a Duby array AST node. So it basically just creates a new one, creates a new array node, and then for all of the child nodes in the Ruby AST, it's going to transform them into Duby AST elements and add them to the list of children here. If we look at the literal, literal AST stuff for Duby, here's what the actual Duby array node looks like. So it has a parent that's always bidirectional so that you can work back and forth. Line number and all of the logic is basically done by the block to add all the children to the array. Here's a bit of the type inference logic. In this case, it's just going to use whatever the type inferring engine, which is the current one that you're using, considers an array type. And in the current version of Duby, your array type just becomes a Java util list. And it will actually produce a list for a little role array. Now if we look at the first part of the compiler, this is the part that's common to all the languages. It's just decorating all of those Duby AST nodes with a compile method and passing whatever compiler in. So for each of these nodes, it's going to call into the compiler and say I want to emit a fix num now. I want to emit an array now. I want to emit a method definition now. And the last part of that is here in the, this is the JVM version of that backend compiler. We've got our array method that takes the node and whether it's being used as an expression. If it's an expression, we're going to create an array list, a Java array list, and then populate it with all of the elements. And in this case, we decided that it also made sense that if you're having a array in a piece of code, that it should also be unmodifiable. So you don't have multiple places re, multiple places modifying that in different threads. And now if we take a look here with, if it's not an expression, what it does is compile the internal elements because there's no reason to have the array around the outside. It just runs through all the children and compiles them. So that kind of gives you a little overview of how the whole pipeline for Doobie works and how you can plug some stuff in. There is one other that I wanted to show an intrinsics here. So intrinsics, in here we have an example of where we've actually plugged in to the Doobie compiler chain to add a specific keyword. In this case, we've added a print node and down below we have two macro definitions for puts and for print. And now you don't necessarily need to treat puts or print as keywords in your Doobie backend. But in this case, it turns them all into print nodes and then the compiler knows how to make that do whatever a print is on the given backend, on the JVM, for example. I think that's about all for those demos. Okay. All right, so now the other half of this is that a lot of people like dynamic languages and there's a lot of good use cases for having dynamic invocation as part of a language. Static typing isn't always the right answer and in a lot of times it's completely impossible to do things with totally statically typed language. And one example, one of my three examples is a test-driven development. It's much more difficult to do test-driven development with a statically typed language because you can't even run the tests until you've started to implement the system. You can't compile the tests until you've started to run the system. It's much more difficult and I got into all sorts of battles with people on Twitter when I said this and they said, no, you can. You can do beautiful test-driven development. You just have to stub everything out before you start running your tests and I didn't get the point of that because now I've actually started to write all the backend stuff before the test. I thought the test was supposed to be coming up first so that was irritating. A lot of static libraries also fall back on reflection anyway internally and if you had a nice fast dynamic invocation as part of the language, you wouldn't need to do a lot of reflective stuff. And the interesting thing is that JVMs, for example, are already starting to support fast dynamic invocation at the VM level. So there's no reason that we need to only have static typing as part of languages on top of the JVM. We could have a hybrid static and dynamic. So the first thing I was looking at was doing Suryx. Suryx is basically Duby's dynamic cousin. It looks like Ruby and it uses whatever backend you want it to, but it's all dynamically typed and uses all dynamic invocation. In the version I have, it's very simple and just uses the Java JVM type system. It uses the new fast invoke dynamic opcode on Java 7 and it works pretty well. Performance is pretty decent and invoke dynamic is now getting really fast. And so here's a quick example. So here's the Ruby code. Well remember this, here's the Duby code. Let me try and keep up here. Here is the Suryx code. That's kind of subtle, but there it is. Okay, now what happens here behind the scenes and this is probably a little too small. Let's see if we can get a little close up here. So what actually happens here is rather than generating the code we saw before for doing standard Java like fib with primitives, what it's actually doing is it's using all boxed objects so they all become long objects. You can see it's, we load, let's see here, we load in the value two as a long and then here we're constructing a long object. So all of the literal numbers now in this case become objects and when we do calls on them, for example the less than call, it's actually using the JVM's invoke dynamic operation to do that call. So where we had a simple plus operation, native opcode for long plus long or int plus int, now it's actually doing the call and that call on the back end and the Suryx back end does essentially the same thing. It takes the two boxed longs, does the addition and then returns a new boxed long as a result. Let's go back out here. I think this one's a little, no this is good. Okay, so where does this all fit in with Doobie? And why would we have two languages that are essentially the same thing but the only thing that's different is the, whether they're statically typed or dynamically typed. It doesn't really seem to make a whole lot of sense, right? Why not have something like optional static typing as part of Doobie? Then you can gradually specialize things for performance or if you want to go back and do dynamic invocation in particular cases, you wouldn't have any performance penalty like for example groovy, you can add static types to all of the signatures and you can static type everything and make it essentially look like Java and it will actually run slower than regular groovy code because all it does is add a bunch of run time type checks all over the place. It doesn't actually statically type it, which you know, that's an interesting myth that a lot of people don't know. So what about dynamic invocation? Just being able to have access to dynamic invocation. Anybody that's ever had to do any reflective calls on dot net or on the JVM knows that it can be pretty painful, lots of exceptions to catch, lots of extra calls to find the right method and make sure you get all the types converted correctly. Why can't we just do dynamic invocation when we can't determine statically what the type of this object is? And so that's exactly what I want to do. I am going to try and urge the two languages. Doobie will essentially just become a hybrid static dynamic language and you'll have the benefits of both in the same language along with all the pluggable stuff and all the pluggable backend as well. And it hasn't been done yet, but it's going to be in progress and I don't see any reason to have these be two separate languages. And I put this in here for Tom. They're your types. Use them when you need them. All right. Some people get that. Some people don't. Okay, so what does this all fit back into JRuby? My primary language project. Well, these are ideal test beds for trying new things out. So horrendous, terrifying things like Ruby with optional static types, which some people fear and some people secretly wish they could do in localized cases. Or just the ability to do a little bit better unification of Ruby and Java types so that we don't have quite so much overhead going across the Ruby Java border. It's another possibility. Important to remember that doobie and syrinx are not Ruby. So JRuby still has just as much validity. You do not, there's no rails running on doobie or anything like that. There's no core library other than whatever your back end runtime provides. So Ruby is still needs to be there to provide all of that. But it doobie and syrinx can go along with and help help evolve JRuby and help provide another tool for Ruby is to develop with. And it's good practice for playing around with this stuff. I get to play around with open-vote dynamic. I get to do lots of byte code emission, which I think I do more than any other language these days. And you know, it's kind of driving where some of JRuby development can go. All right, so, since I'm getting close to the end here, it's your turn to do this stuff. I've been hacking on this, it was only me up until this fall, playing around with stuff, getting the type inference to work, getting some basic Java examples to work. Then Ryan from Google came along and he implemented a whole bunch of additional syntax, a whole bunch of additional features for doobie. But I would love to have more people involved. I'd love to have people work on the type infer, I'd love to have lots of back ends. There's a lot of potential here for a very flexible, very extensible language that looks and feels a lot like Ruby but can target all sorts of back ends and be just as fast as writing in all of those awful back-end languages like Java or C-sharper and the other ones. There's this idea of the semantic gap that I wanted to try and mention. In a lot of these languages, we've lost track of what's actually happening when we write a piece of code and how much overhead we're introducing into the system. We have no idea in Ruby how much x86 code is actually running. It's an insane amount of work that's actually being done to do Ruby. But even in languages like Scala, just introducing one or two new features can suddenly introduce massive amounts of code and massive amounts of overhead. And so there's this gap between what we understand as the semantics of the language and what actually happens on the hardware. Languages like doobie I think can help eliminate a lot of that gap because you do know exactly what's being emitted in every case and you know how to weigh the cost of adding new features. And of course, watch doobie and JRuby this coming year. There's gonna be a lot of work done on both of these and hopefully both of them will kind of help each other along. Here are a few links. I did register doobie lang after wrestling with GoDaddy for about an hour. But there's a project page. If you wanna look at byte script, the JVM script project on Kenai is the one. And then basic content information. So at this point, I would love to have questions from you. Yes. It seems like it would be really awesome to use doobie to do selective optimization in a larger JRuby app. Yes. Is that reasonable or are there any gotchas that would give them the way of that? Well, there's two ways that you could look at doing that. The question was, the comment was about being able to use doobie to selectively optimize pieces of Ruby code. The first and dumbest way would be to use something like Ruby inline and have a doobie inline that just throws some doobie code in there. It should still basically parse with minor modifications and then you could have doobie code embedded into your Ruby code. But it still isn't really two way integration. It's still creating a piece of Java code and Java methods that then get integrated through JRuby's Java integration. That would work and I'm gonna have that. I've got a Java inline gem that now has scholar support apparently. But it's gonna also have doobie inline support. So that's one way that you could do it. If you wanted to implement a mathematical routine in doobie right in the inline with your Ruby code, easy to do. But the other way would be being able to actually use Ruby's types in a more static way. And that's where kind of the optional static typing potential for JRuby would come in. What we've learned from doobie and how it can do type inference and how it can figure out what actual types are being used and make the invocations a little bit more concrete, that would probably be the better way. So I would expect that is more something that JRuby might evolve as a third arm of some kind rather than that specifically being what doobie does. Okay, other question. How about the front? Are you planning to rewrite some parts of JRuby and doobie? Ah yes, planning to rewrite some parts of JRuby and doobie. Well, the only thing that's really missing for us to do that is various little Java features that aren't there. Things like accessing static fields, some of the more complex features like annotations and whatnot are not there yet. But yeah, I would love to. I really would love to write anything in JRuby using doobie. There also has to be, it has to be worthwhile making the translation from existing Java code to doobie code, but probably wouldn't be difficult to create a Java to doobie translator. And then we'd have the first fully transferable, what's the term, round-trippable, round-trippable language that can go back and forth between Java and something Ruby-like. And then nobody ever needs to know you're using doobie actually. You can have it as a commit hook. It just turns it into Java and then pulls it back out and turns it into doobie again. And that's kind of an evil idea, but I like it. But yeah, I would love to. And I've heard from other folks that have to do a lot of Java on a daily basis, like for example, Ryan from Google again, doing GWT, for example. You have to write a lot of code. Perhaps some of you saw all the code that you have to write for GWT in one of the earlier talks at the conference. Being able to write that in doobie, have it output a .java file, and that turns into a GWT application. Well, that's much better, much better way of doing this. So I'd love for anybody to start using this in place of Java, and that's the goal. In the next row. Oh, what Rubinius says. So you can have more people. I bet you can have more people working in doobie than in Java. Yeah, that's good. We can, you know, force change that interchangeably. Yeah, yeah. And that's kind of the original goal. The fact that Ruby's syntax, at the very least, is so much more approachable. Having the full set of Ruby types is also nice, but you know, it's not a bad thought to have what essentially is a reduced subset of Ruby. Looks like Ruby, generally feels like Ruby, with closures and methods, and the way that Ruby is like to work, have it actually be native static compiled code. And so that was one of the goals, and you know, eventually when doobie gets to that point, we'd love to have as much as possible of J.Ruby written in doobie. I think over here. How fast is the invoke dynamic versus static? So like on the practical example. Okay, so the performance of invoke dynamic versus static invocation. For equivalent work, which would mean the Java code also using all boxed math and virtual calls for addition and whatnot. It's only about one and a half times slower. So that means that using normal objects, rather than mathematics, would be only about one and a half times slower doing all dynamic invocation throughout. So they've done a great job on invoke dynamic, and I think they're probably gonna be able to get that even closer to one than it is right now. But the other problem with this right now is that using all the boxed math is much more overhead than primitives, and the current JVMs don't eliminate all of the boxed mathematics. So you probably wouldn't want to use SURINX and the dynamic invocation stuff to do a lot of math that could be done faster with primitives, but for manipulating objects and walking trees and constructing stuff, that's pretty close to being as fast as Java. I think the goal that John Rose mentioned was that they believe they can get invoke dynamic to be as fast as normal Java interface invocation. I'm here in front. Does it run on Android? Ah, does it run on Android? And that's actually one of the goals that I probably should have added in here. Because this outputs just normal.java.class files, it'll run anywhere Java does. You can run this on the smallest embedded Java device. It's just .class files, it's just byte code. So you could use this to do an entire Android application if you want. You could do this to do embedded Java or real-time Java stuff, but at the same time, you could use it to do Java EE. It would work just as well, because again, it's just a swap for the Java C outputs, and that's all there is to it. Over here. How much of the Ruby metaprogramming is supported in Doobie? All right, well. Metaprogramming is really more of a type system feature. And so, since Doobie has pluggable types, it can do whatever the type system does. On the JVM, types are not particularly metaprogrammable. So you can't make manipulations at runtime. You can't define methods after the type has been loaded, et cetera. However, you can do what some people call compile-time metaprogramming by adding in some plugins that know specific keywords, specific little bits of code within the class body. It can do things like generating attribute accessors programmatically at compile-time, generating a bunch of code for you. And then what actually comes out is as a final type, and it doesn't mutate after that. So you can get some of the benefits of metaprogramming out of that sort of compile-time transformation, but not as much as Ruby without having a type system at runtime that's actually mutable enough. A lot of stuff that you can do with Ruby though, you can do with features like having implicit type coercions like Scala has, or having a structural typing. So you can say, I want any object that implements two string, and I don't care what the type of it is. Things like that could be added into Duby very easily, and give it a lot more of a dynamic feel without actually making it dynamic. Right here. Do you have your own core types, or when you do a hash literal, is that actually like a hash map? Or is it something like that? Right, so does Duby have its own core types? No. It has no core types of any kind. All the type inference logic is done basically just with symbolic representations of what a type is. It's something called a hash, or it's something called a fixed num, and then that propagates throughout the system. But what you do when you want to implement it for a particular backend is you add additional behavior to what a fixed num type is, or what a hash type is, so that it knows how to do calls, it knows how to do math, et cetera. So the type system is defined by you for a given platform. So it's kind of, it's almost a meta language, but with the JVM backend it becomes a nice JVM language. With an Objective C backend it would become a nice Objective C backend. So that's all there is to it. Yes. Closures? Closures. I think we have some closure stuff starting to work now. In the Java case, closures would probably just map to a really nice looking anonymous inner class. Look for an array and just implement the array. But there's also various compiler transformations we could do. So if you wanted to say that all Java util collections have a map method, well we'll just have a compiler plugin that knows that collections have map and then do a map operation to create another list out of that. Those sorts of things would be very easy to add as just little compiler plugins to modify how that code generates. Do you use Ruby's style of nesting, of flexible nesting and stuff like that? I mean is that the model? At this point it would, well again, it kind of depends on the backend. If closure's mapped into, so the question is about whether it's the same sort of lexical nesting that Ruby does. If it was mapping to anonymous inner classes, the nesting would be that either they're carried along as final values as in Java's anonymous inner classes or they're carried along as little boxed values. And so only the ones accessed from the closure would be accessible from the inside. But it is Ruby parser, so the structure of the parse tree at least does match what Ruby does. And then you can decide whether you want to flatten that or whether you want to map it to final values. Or for example, if you wanted to do something like closure and make anything that's used from closure of the language and anything that's used in closure of the structure be a ref and have to be mutated in a sync block, well you could certainly add that and that would just be implicit as part of the language. Other question, how much time do we have? 250? I think I started at 210, so we've got a little bit more. Yeah, yeah, Paul. To run, well the only thing that actually depends on JRuby or the Java platform is the compiler chain. And there is actually a. As well, so I wasn't sure how much else does it require Java. Right, well once you've actually produced the code, whatever the code that comes out of the backend of the Ruby compiler has no dependencies on anything implicitly. If you explicitly build something that's for the JVM and uses specific libraries on the JVM, it would depend on that. But for the most part, the only reason that it uses JRuby is because I'm using, I've got the JRuby parser which is written in Java and I've got the ASM output which does Java. None of the results of compiling something with Ruby depend on JRuby in any way. And there actually is a stupid non-working C version of the backend that outputs broken unparsable C, but again, this is an example of how you could easily modify the backend to output just about anything. Okay, Ola. Generics? I'm sorry. Well, so the question is just generics. Generics are, they're an interesting feature that a lot of static languages use to get around the fact that they can't specialize particular collections and can't specialize particular algorithms and things and that's nice and it's useful. I don't see any reason that Ruby could not support generics. You'd probably have a compiler plugin that says, okay, for the subsequent method or the subsequent class, it's going to use this generic type or it's going to use this type reference to parameterize it. I don't have any desire to add that right now. It certainly could be added by somebody else, but yeah, at the moment, there's no generic support and I'll probably delay working on that as long as possible. Yehuda. So it would probably work, so you peed someone after earlier about rewriting parts of JRuby in to the, it would probably work check to see what the missing features are. Oh yeah, yeah. Could it be a list of things that actually are not? Yeah, yeah, and actually a list of features that are working would be useful as well for anybody who wants to play with this. So that would be the next thing that we'll probably do. I played with it a couple of times and said, oh, can I reimplement this little piece in Duby and then there was one or two things missing and then I walked away, but I didn't note it down anywhere. I'm hoping that if we get more people involved, people start trying things out. We can start kind of collaboratively figuring out what Duby should look like on platform X and platform Y and then figure out where we need to go with it. And at the moment, it's not quite even up to the level of Java 1.0. I'd like to get to a 1.0 or so before we do like a 1.0 release of Duby and then kind of move forward from there, so. Woody. So I would imagine pieces of JRuby, like Ola's YAML parser, could be plugged in very easily and there's also extensions that have pieces of Java in them. How much work is it to integrate existing gems that have heavy lifting in Java into Duby? What's involved there? I wouldn't take too much at all. Again, as long as the Duby compiler supports all the language features of whatever Java code is in a given gem, it could very easily just write that all in Duby. There is a Duby gem that you can install on JRuby and you get all the commands and I think it's 001 right now. And then you could have it all compile at runtime. This all just can generate classes at runtime like normally or compile on install if you really want. But it wouldn't be hard to start taking any of the pieces of the existing JRuby extensions and replacing them with Duby code. What's your motivation for having multi-platform support versus just making the best Ruby-like syntax you can for JVM? Well, I go back and forth. The question's about what's the motivation for having multiple backend support or platform agnosticism, as I like to call it. The original plan for Duby was to be platform agnostic because I was hoping that some of the other Ruby implementations would like to use this. And they were too busy to really work on it or they didn't care or they didn't like it or whatever, I don't know. But so then I said, okay, we'll screw you guys. I'm gonna do it myself and I'm gonna make it really work on the JVM and work solidly. And now that it's a year or so on since I first made the proposition of having a platform agnostic Duby and it's looking interesting and people wanna play with it again, now a bunch of people are coming to me and saying, hey, buddy, I'd like to have this, I really like to make Duby work on my platform and output objective C or use closure or use LLVM or whatever. And so I'd love to have that happen. I'm gonna try and make sure that all of the core logic of Duby and the pipelines for the compiler don't impose the JVM upon you but I'm probably not gonna spend a lot of time on any of these other platforms because the JVM is my platform. So if other people wanna back-end it on any of these things, I will help you do whatever, I'll help you in any way I can. Any other questions in the back? Yeah, you mentioned use of invoke dynamic, is that, does that mean CERNX requires the JDK7 or what? So using invoke dynamic, does that mean CERNX requires JDK7? It does it at present and dynamic invocation in Duby would probably also initially require JDK7. But again, there's no reason that it couldn't also support earlier JDKs and do all reflective invocation with a little bit of caching logic. I just haven't implemented that yet and haven't decided whether I really wanna do that. If that would be interesting and people think that, yes, I would like to have a Duby or CERNX with dynamic invocation working on previous JVMs, it'd be a couple lines of code to add that. So, there is also, yeah, this is a good point. Ola mentioned that there is a back port of the invoke dynamic support that works on Java 5 and Java 6 by doing some byte code manipulation. So that's another possibility. If Duby or CERNX output invoke dynamic-based code, you could probably use it with the back port and still run it on the older versions. And I see folks are coming in, so I think that'll be about it. And you can grab me or talk to me at JRVConf tomorrow. Thanks.