 So, I'm giving a talk about three or four months ago, and I left my backpack in the back of the room. I forgot to turn my phone off. It starts ringing halfway through my talk, and everybody's looking around, like, okay, who's the moron? And finally I'm like, yeah, that's me. I can't do anything about it. So, let's talk about domain-specific languages. It's late at night, which actually, at first I was kind of like, you know, what's going on? But I think it's going to be good, because this is a little bit more hand-wavy. This talk is designed as much for Ruby developers as it is for other developers who want to understand why they should use Ruby. It's kind of my part, too, as to why I absolutely love this language and why I like to use it. And it's going to pull on some of the stuff that Giles talked about, some of the stuff that Jeremy talked about. In fact, Jeremy, thanks to a comment he made, caused me to add in like five slides up there. So, my rhythm's a little off, forgive me, but hopefully you won't notice. So, like I said, this is kind of the why I love Ruby. So, what are my goals? First of all, why you should look at Ruby. Most of you have already heard, most of you have already looked at it. I have spoken to some people who, you know, this is kind of an evaluation period. So this is yet another, you know, why you should really do this. Also what else you can do with Ruby? Because a lot of us come in, one of the, my favorite quotes of the day was Ezra, who says, you know, a lot of people come for Rails and stay for Ruby. And so this is kind of that demonstration as to what else you can do with it. And then of course, why I personally can't shut the hell up about Ruby. So, I made it, you know, when I was growing up, my dad was one of those guys that loved to make a bunch of goofy crap. So he was a pilot in the Army and everywhere they went, they'd give him a bunch of maps, and so his proudest moment was making this map book that he had. And he would spend all this time putting them together and creating this big book. The problem is the outside cover was always in duct tape. You know, as a teenager, your dad's walking around with this thing and it's just so embarrassing. And he would never buy things. He would always just make the things he needed because it was just, you know, giving some wood and some duct tape and he'd come up with some weird solution. And it was kind of weird, but after a while, I kind of started discovering that as I started becoming a developer, I'm very much like my father. So, who am I? Well, my name is Joe O'Brien. I founded a company called Edgecase in Columbus, Ohio. I was a former thought worker. I realized that a 747 for commute kind of sucked. So I started my own company near my house. Found at the Columbus Ruby Brigade because I got tired of going to my wife and showing her really cool things that Ruby could do and having her roll her eyes at me. About 300 people strong on the list. We get about regularly 50 to 60 people attending, which for Columbus, Ohio is absolutely mind boggling because that's not exactly capital Mecca of the world, right? I have a very large .NET J2E background. My specialty was enterprise application integration, SOA, those kind of things. I love the big hairy balls of mud. You have to join with some other big hairy ball of mud because you've got 16 years of really stupid technical decisions. I find those really interesting. But one of my passions a long time ago, thanks to my mentor, was XP and Agile. And I spent a lot of time selling into enterprises and these places a better way of doing things. And while I was doing that, along came Ruby. And it was kind of this interesting fit because we were preaching that better people and better process make better software. But all of a sudden, we said better people, better process and a better tool make perfect software. And with that being said, the biggest reason I have this side up is not because I'm arrogant like Evan said, don't be. But it's because I want to tell you I'm not a Rails guy. We do mainly Rails development right now. It's hot. It's selling. I like to get paid for what I do at times. So, but I'm not here to tell you about Rails. I'm here to tell you about why people stay like Evan said or like Ezra said. And I also love Emacs. And we'll get into that in a bit. Alan Perlis has a very famous statement and it says, a language that doesn't affect the way you think about programming is not worth knowing. We all love to throw out the fact that, you know, the Pragues say that every year we should learn a new programming language. But a lot of us, when we make the choice of what programming language to use, go for the safe features, right? We're in programming, we decide, I need to know JavaScript a little bit better. Not just think on JavaScript, it has, you know, there is a real language in there. But we always tend to go for those safe options. And Ruby is a really interesting one if you haven't already learned it to learn because it's really going to affect the way you think about programming. Yes, you can write Java code in Ruby. I recently found an old backup desk of mine and I was going through it and I found some Perl code. I was like, wow, this is really interesting. Back when I was doing Perl and I remember the time frames. I started digging a little harder and sure enough I found my original Ruby scripts. And it was really cool because there was Java code with Ruby syntax. I really just hadn't understood what it was that you could do, understood these concepts. And so it was, this is what happens late at night. I completely lose my train of thought. So that thread's gone, let's move on. So we've all heard of the Mythical Man Month, I'm sure. I hope, if you haven't read it, put it on your list. But Fred Brooks talks about the fact that they did study after study and we came up with the fact that every programmer can produce about on average 1,400 lines of productive code, production code a year. The number's not important, but what's important is we discovered that there's a finite number of lines of code that each one of us can produce per year. Unless you're Evan Phoenix or Ryan Davis, that's pretty much a standard number that's gonna stay there, right? So what we need to do is start figuring out how to be more productive with that code, how to produce more. This is not news to any of us. We've been doing this for a long time. We started off, everybody has the base assembler. And apparently poor Josh actually wrote in that for quite some time, as I discovered this morning. And then we discovered that we wanted to abstract that at some, make it more portable, so we went to see that eventually compiled down, eventually compiled down. And then finally we found a language or languages that produce more, that produce more, that produce more. But we're still missing another step. We've also discovered that what's really cool about this language is it's very expressive, but we're trying to do the same thing again that people have done time and time again. And that's this bridge between Ruby and C. So we are now presented with even better options, which is let's start harnessing that knowledge that's already been gained out in the industry and look at the JVM or the CLR with DLR edition, or even Rabbinius, which I find absolutely fascinating. Because for quite some time we've been out there going, okay, let's not worry about speed, let's see what we can do with this language and somebody will solve it and sure enough somebody did. And that's what's been fascinating. But we still want to find how we can be more productive with the code we have, and we can do even more than we're doing right now. So a couple years ago, when OOMG comes out and says, I've got an idea, let's all draw pretty pictures. We're gonna draw pretty pictures that are gonna represent our domain and we're gonna generate the code that we're gonna do. And as my mentor likes to say, hieroglyphics worked really well for the Egyptians, but only to a certain point in time. Eventually they had to go to a real language too. So we get our languages and we're told that everything's a tree. Life is a tree, we can put everything in these nice structures and we start going about and we start doing this programming. And that's one of the places where I loved Jeremy's talk just a minute ago because he said these languages we've been using, Java C sharp, are like Lego blocks. And I think that's a really cool analogy because you can do a lot with Legos, you know? I had my big bucket of Legos at home. Okay, I had, I still have. It's a cool thing about having kids, you get to play with this stuff again and it's not considered stupid. But you could make different things. You could make robots, you could make dogs, you could make computers, not a working computer, but you could build these structures up from these blocks but you still had to use a little bit of your imagination to figure out what was going on because you didn't have exact rounded corners. You didn't have the ability to go that extra little step that you could. We also are told everything's a tree but what they don't tell us is what the forest really looks like, right? You get into your first enterprise, your first enterprise, a big company job and you get in there and you start looking around and there's dead trees everywhere. There's moss growing on things. Things are crossing each other and things are growing off of another one and so this is what reality becomes, right? So, switch gears for a minute. I've had several career paths and one of them I worked for a small company that made culinary artwork. Talk about a niche market. Turns out that chefs like to be decorative. They like to be expressive and artistic and it's amazing what they're able to do but they have one role. It has to be done with food because it's cheating if you bring in, you know, a Picasso and shove it on a buffet. You know, you have to create it with the food that you're doing. And so this guy I was working for created this stuff called, well, he didn't create it. He found a way to purify this stuff called tallow and then back in the 60s this became really popular with chefs where they would make these sculptures and these decorations with the stuff that was purified beef fat, basically. But the problem was it went rancid. And so the FDA eventually said, yeah, this kind of is not a good thing and did away with it. Well, Dominic comes along and figures out a way to purify it and get it up there and make it so it doesn't go rancid anymore. And he gets quite the business going and he has all these sculptures that he sells that are pre-made. But the most popular thing we sold was bulk tallow and we sold it in three grades. Casting tallow, which was really, really hard. You pour it into molds and it sets really hard. You had carving tallow, which works very much like ice except it doesn't melt on you. You use the same tools you would fry for ice and you carve things away. And then we had molding tallow. Now chefs could take the stuff and you could mix it. We would sell it in plain tallow, cheddar, or chocolate. So now you're using food, using food items and creating buffets. And the cruise lines love this kind of stuff because they create these extravagant buffets. And they also love it because they can have reusable things because before what they do is take a block of cheese and put it out on the thing. Well, then the next dinner service comes up and they'll use it again. The next dinner service comes up, they pull it out and they go, it's starting to get a little green so they'd carve it up and make it a little smaller sculpture and so forth and so forth and eventually toss it overboard. But now they have something that was reusable. What was interesting was the three grades that people would use. And we got into a culinary right up on time. And it talked about how it was basically a chef's competition. They have the chef's Olympics like once a year. And this guy I got to know, Lou, I can't for the life of me remember the guy's last name, but he was like the chef for the Olympics, right? This guy's got a huge job. But his job at the time when the Olympics were every four years only worked for two year bands because there was a lot of planning, implementation, everything that went into it, but then he had two years off. And so he would do these Olympics, he would do these different things. The things that he would wanna make, he would use all three varieties of talla that we made because there were certain things that needed to be cast, there were certain things that needed to be carved, but in the end, there were certain things that just had to be molded by hand. But if you're making a tree that's life-sized and stands this tall, which I saw him do, you can't do that with modeling clay. We also have discovered that drawing pretty pictures in these different things that we tried to do is interesting, but we're tacking the wrong side of the problem. Gartner did a research study years ago that talked about the total cost of software. And they took a software project over its lifespan, say five years, and said, what is the total cost? And they went to all these different companies and talked to it and did whatever the hell Gartner does and gets their money for. But they came up with a figure of 85%. Software in life cycle and maintenance costs is 85% of the cost of software. So all of these technologies we're doing to make software development faster, we're attacking 15% of the problem. And this is where I really like to get into software because I am not the math guy. I am not the smartest developer. Jim will attest to that, poor guy, I had to pair with me for nine months. Because of that, I don't look at, you know, cute little tricks and things and get it right away. I like readable software. I like it very, very expressive. Those five cycles that it takes me to figure out what the hell somebody was doing, I don't like. So I tend to take my time focusing more on reading versus writing. What do we do? Well, I personally, I'm a business software developer. So we make software for businesses. And all of these businesses have established vocabulars, established languages that they use. Who knows what this one's from? Somebody. Thank you, Waffle House. I gave my first ever DSL talk out in California, put the slide up, silence. So I had to create this one. But what's interesting about Starbucks is they really do have a DSL. Okay, yes, part of it is, you know, but I just lost the word. You know, part of it's an air get thing, right? The whole venti grande thing. Although I really want to get to Nexa Chat Fowler one day and whisper into your venti, because I know it bugs him. But they have a distinct order and a distinct vocabulary that they use. And if you ever wonder why they do this pretentious, that's the word I'm looking for. Why did that come to me now? I don't know. ADD kicking in. All of us look at it and think it's this pretentious vocabulary. And you know, you go up and I've had, you know, I've got up my standard order, which is very simple, but every now and then I'll get some fancy drink. And I always try to get the order right and play with it. And inevitably I walk up and I look at her and she smiles and says, okay, she turns around, she reorders it and, you know, changes the order on me. I'm like, damn, I can't figure out what she's doing. But then you walk into a Starbucks at eight o'clock in the morning in downtown Chicago and they've got a line out the door and it's 30 degrees out and people are mad. You notice that line is moving like none other. If you take this vocabulary away, things start breaking down, mistakes can be made. And this is how they get around that. We also look at some very successful DSLs, some very successful models that have been used. And Microsoft Excel is another one. As much as most of us hate it, if there was one piece of software we took out that would take down 85% of the economy, it's Excel. When it came about, it was so successful because finally we gave them software that was a mental model match for what they did. It was columns and math and accounting and you could sum up the, oh my God, it made sense. So now we have lead generation engines and all this other crap that people put in spreadsheets and then it's our job to translate those, right? So domain-specific languages. Just like its name says, there are languages that are very specific for a particular domain. But what's interesting is this use of domain because a domain can be really small and it can be really large. That's some of the things I hope to talk about today. And eventually Jim's gonna start shouting at me at the end of this because he and I disagree very big on this right now. I mentioned I love Emacs. All right, Martin Feller, I absolutely love Martin because he's not one of the guys that's out there trying to tell us what's gonna happen next year. Martin's job is to tell us what we've done. He works for ThoughtWorks, chief scientist as some of us say chief cheerleader. But what he does is he goes and he watches what people do in software. He watches what the trends are and takes a step back and looks at patterns. But more importantly, he gives us language. He gives us language we can use to identify these things. Because what we all love to scream and moan about design patterns, what design patterns was trying to do is give us a vocabulary we could all harness so we could start communicating better about what we were doing. You know, I did this really cool hacky thing. It kind of did this and you just put the object in there and then, okay, well fine, we have a visitor pattern or we have, you know, the single tenor, we had these names for things. So Martin is working on this for DSLs. Thank goodness. And he's got his work published and the DSLs work in progress and I highly recommend you go look at it. It's language agnostic and it's very, very interesting. So he defines DSLs and I'm gonna steal a lot of his vocabulary. So DSLs is a computer language that's targeted to a particular kind of problem rather than a general purpose language that's aimed at any kind of software problem. So I'm not up here telling you is write your own version of, you know, scheme whether you take the bus or not. What I'm not telling you is to talk about is to write your own JavaScript. What I'm telling you is we're talking about very specific problem sets that we're trying to solve and that also, by definition, means they're not gonna work in general scenarios and that's very important. You know, the metaphor of craftsman's been beat to death but it's a really, really good one in so many ways. This is another one. If you look at, if anybody watches PBS and sees Norm Abrams, please tell me people know who Norm is. Oh thank goodness. Again, gave this talk two weeks ago. I said, Norm Abrams and Crickets. Who knows who Norm Abrams is and nobody raises a hand. I'm like, oh crap. Despite the fact that he's got the world's biggest budget for any single carpenter and he can pull out a new router every time he wants instead of changing a bit, you'll still see that Norm has a lot of jig setup. He has feather boards. He has special jigs that he sets up for certain scenarios because you can't buy every tool. And this is kind of what we're gonna start talking about is building these sets of jigs and evolving the things we're doing. And then eventually you get an entire collection. And so when you go to make a window, you know where to go. When you go to make a desk, you know what you're gonna do. When you go to build a model bridge, you know what you're gonna grab. These can be small, these can be rather large. You know, there's scaffolding out there that helps us do these things that are very particular. There's jigs that are built for one time use, like if you're building a boat, because it's gonna take a while. You might as well have something to set it on. And there's a very distinct way to build a jig that you build for a boat that you're eventually gonna throw away, but it helps you in your development. And this is exactly what we're talking about. This is also not a new concept, okay? Because there's always gonna be somebody in the audience who's gonna talk about how they've been programming longer than I've been alive, and they're gonna say, yeah, we've been doing this forever. You're right. And in the Unix world, they call it mini languages. If you haven't read it, the Art of Unix programming by Eric Raymond is one of the better books to read on software development because it gives you a lot of the ideas of what we're doing. And as I look out in the crowd, I see very few Dell's and IBM computers. I see a lot of Macs. All of us are running on Unix. If you really wanna understand what's going on and why, read that book. Okay, off that soapbox. In there, Eric Raymond talks about mini languages. And he talks about this tradition in Unix of there's times when having your own language or something makes sense. There's times when it evolves and it's just freaking ugly. Send mail config comes to mind. Okay, this is the one that everybody uses, right? You sit there and you use it for the first time. You stand back, you grab a beer, you guzzle it pretty quick and you go, who the hell in the right man came up with this? Well, truly, it's years of stupid decisions and not really planning it out. So, and he uses that as an example of start looking towards what you're doing. Don't necessarily map out a language from the beginning, but start looking towards it. We also need to split things into two categories. And here's another place where I loved what Martin did because he gave us two definitions, external and internal DSLs. So, we're talking about languages. We're talking about mini languages, but we're talking about two different ways of doing them. So, who here has used Lex and Yak? All right, keep your hands up. Who enjoyed that experience? Okay, that's all. Antler. Antler, yeah. What I'm gonna be talking about, mainly, is the internal DSLs. Which is, I'm not gonna cover Lex and Yak, I'm not gonna cover Antler, I'm not gonna cover these things. You can go do these, okay? But these are very much planned out. What I'm talking about is a style of development. And we're gonna talk about internal DSLs. And I'm gonna steal from another really good guy to go from. Or as Giles said the other day, the guy that made a lot of money from Yahoo and has been blogging about it ever since. Paul Graham talks a lot about list programmers and the way they work. And it's really interesting because don't blow off the fact that he's using Lisp and telling you you should use Lisp for e-commerce. He really is trying to tell you that. But listen to the message that he's giving underneath. And it's the style of development, okay? And he says that list programmers follow a principle which could be called bottom-up design. They change the language to suit the problem. And now I'm gonna break every woman presentations then and give you this quote. He says, in Lisp you don't just write your program down towards the language. You also build the language up towards your program. Language and program evolve together. Like borders between two warring states, the boundary between language and program is drawn and redrawn until eventually it comes to rest along the mountains, the rivers, the natural frontiers of your problem. And in the end your program will look as if the language had been designed for it. When language and program fit one another, well you end up with code which is clear, small, and efficient. And so this is really interesting. He's saying that just like two warring states, they go back and forth, but there is a natural frontier for your problem. There is a natural frontier that these borders are eventually gonna be drawn upon. And that's what you're trying to do. You're trying to find those boundaries and you're gonna go back and forth. And warring states is a really interesting way to look at it because it does. It goes back and forth and ebbs and floats. Study World War II history, study some of these other things and you'll see a lot of these boundaries go back and forth. That's what we're aiming for. So why aren't we using Lisp? Because it is the world's most natural language, right? No. Also again, misplaced slide, wanted to stress the fact that I'm talking about Ruby, not Rails here, okay? I'm really talking about what we can do in the language. Rails is really interesting to look at though because it's a demonstration of this I think. I feel like it's a really good demonstration of this. So if you look on the front of rubylang.org, Matt's has a really powerful statement and that says he's trying to make Ruby natural, not simple. So there's a really interesting implication in that in that with this language that we have, we all think of it as this very simple thing but he's not going for simple, he's going for natural. He's trying to give us something. And what's also interesting is Matt's did not, whoops, okay, another random quote. I've got more cuts to the ordering of this. Programming languages should not be designed by piling feature on top of feature but by removing the weaknesses and restrictions that make additional features necessary. This is from the revised report on Scheme and it's kind of one of those things that really lets you start seeing why Matt's chose to do some of the things he did in the language. He did not sit down to write a language you could mold and manipulate and do DSLs in but he created the perfect storm. He gave just the right ingredients and this just kind of exploded, okay. And what were those ingredients? Well, small talk, Lisp or Scheme, Python, Pearl, and some really good ability to see things in a very natural light. He takes these and he sprinkles them together and he comes up with this language that's really powerful for us to use, very easy for us to learn and it's gonna take us, it looks like a lifetime to master. The first one is the fact that it's interpreted. One of the main ingredients coming from these, one of the main features coming from these ingredients is this idea of the interpreted. That helps us as people who wanna write DSLs way more than we could ever get help if we were compiled. The other is the fact that it's purely object oriented. Numbers are objects, nil is an object. This gives us a lot of really nice ability, a lot of nice air handling and out of graceful way of dealing with things. Of course, we all know the flexible syntax, no end of lines, no parentheses for no reasons. We have our open classes, which we've talked about, which where you can add behavior where we think it should be in the context for what we're dealing with. Unlike some languages that we know where they decided to name class final, the string final, and then from then on, every Java and C-sharp developer has a string util and a number util carried around in their projects because yet we thought of new features that we needed. The small talk influence, where we're passing messages to objects to see if they can deal with it, we're not calling methods that are predefined. This has really large implications. This idea where code is data, we package up code and we send it along to parameters on a method. Well, we can do a lot with that when it happens. The idea of implicit self, personally my biggest reason I hate Python because you can constantly have to tell it who the hell you are. So, the question, one of the questions that always comes up is what is that boundary between an API and a DSL? And I've got credits at the end, I'll show them to you, but I owe this definition not to Neil Ford purely, but he says that, you know, the difference between an API and a DSL is context. Ruby is a very context specific language and in an API you constantly have to tell it where you are, you inject the context into it. With an API you know where you are and you just derive things from that. So, back to the reason I love Emacs. I really had a hard time grasping this idea of context until I started looking at the editor I was using. And Emacs is not the only one to do this, but it's the best one. But depending on what kind of file you're in, depends on some of the operations that happen. There's always this idea of context. It makes assumptions about where you are. I don't know if you guys have noticed, but we're in a very context specific language in Ruby. What we use in Ruby is very context driven. It's very driven on where we are at what point in time. So, I'm using the reflection of glass on my slides to figure out where I am. Well, somebody's playing with the lights on the hallway and it's really screwing me up. It's getting interesting. Shift over some so I can't see that. But it was this idea that when I'm in this file I hit this operation and it does this. When I'm in this file, I hit the same operation or a similar one and it does something different. It's this idea of context, about where we are, when we are. And you can play with that context. You can manipulate that. You can define things in one context and run them somewhere else. And these keys become very important if you want to mold the language. Active record is a really good example. Where we have these declarative, these declarative style that's come about. But it only works in the context of where we are. It works because we know we can assume a lot of things. Convention over configuration is great, but it's only great because of context because we are in that place and we can make those assumptions. So, from Martin's book and from a lot of the work that's been done out there, we are starting to collect some patterns on this. So, one of them a lot of us have seen the Fluent Interface or Martin calls it the Expression Builder, which is supposed to be this nice, I don't want to say English like because that's really, that's not correct. But this way of adding things on to the end and adding more options on, sometimes the order of which matters, sometimes they do not. Again, this is something that other languages have as well as we do. We've seen this in JMoc and some of the other libraries and Jim's FlexMoc library is a great example for us of how this works. This other idea of global scoping, one of the things that Martin talks about in his work in progress is the fact that we've been taught all our lives to be afraid of globals. And this is a fun example because Jim and I were writing a time DSL and we just played around one morning and I kept telling him, I told him the story about how I always get confused between AM and PM when it comes to noon. Like, I can't ever remember which bridge it is. And so, we talked about it and we're like, let's just create a noon and a midnight. And so, where should we put it? Let's put it up in kernel. And so, we did. And we returned, you know, we wrote our unit tests, we set them up, we put them in place, we ran our unit tests, they all failed. We switched them and we ran them again, they all passed. So, declarative programming is this idea that we know from Rails where we're declaratively telling what's happening. We're making a statement. This has implications of being in, you know, of where we are in the class and where we are in the hierarchy and what it's gonna do, for instance, methods. But you look at it and it's like a recipe, it's a very declarative recipe on what we're doing and what we want to occur. Named to parameters, we don't have them in Ruby, so what do they do? They use language level tricks. We use this ability to, you know, send whatever parameters we have into a hash, hash them up and send them in and then we can check for them. Well, now it looks like we have named parameters. Great, so we can take advantage of them. Spillover context was a term that guy by the name of Zach Tampson came up with on a very, I heard about it on a very snowy day in Chicago one time, where we were talking about this idea of what happens in the description of rake. I'm gonna go over this in a minute. And then in the end, what we're gonna do is we're gonna combine them, right? We're gonna take some of these, we're gonna mix them, we're gonna match them and we're gonna use them for the specific nature of what we're doing. So something I forgot to say earlier that I really wanted to say is I'm not up here saying that you should write everything in a DSL. Really, Jim, I'm not. Despite the fact that I keep trying. What I'm saying is this is one of the tools you can have in your tool belt. This is one of the things you can do to take your step, take your code, that next step to the next level and make it that much better. But it's not something you're gonna do all the time. Anyway, more combinations. One of my favorites of all time is Capistrano. I really like this idea of, and then they called them recipes, right? Because with the declarative and with the rake-like syntax, it just has this feel of a recipe. You have your ingredients and then what do you do with them? How do you mix them? What do you do? Really interesting. So let's walk through a tale of three DSLs. Before I do that, let me see how I'm doing on time. Am I doing okay? Yeah. Okay. So Act One, oops, I created a DSL. And this is one of my favorites. So sitting in the audience, Jim Wyrick, he and his friend are talking and he's complaining about make. And any of us that have used make kind of understand what some of the problems were, it was dependencies, right? That was the big complaint at the time. Yeah, dynamic dependencies. He makes the comment that, this would be so easy to do in Ruby. And his friend goes, oh really, what would that be like? And he takes out a napkin and he kind of scratches it out. He's like, I'd be something like this and it'd be so easy to just create. We could just do this. And so eventually they write this on a white board and they're talking about it and he takes a picture of it. But they're talking and they're like, well, we really should get our work done. So they go back and sit at their desks and every good, self-respecting developer, he goes back and does his work, right? God, no. He scratches the itch, okay? So he starts playing with this. He fires up, he max and he comes back and I think it was like 15, 20 minutes later, he's got a first version. He goes running over to his friend. He's like, look, this is really cool. He's like, wow, that's really neat. So what about dependencies? Oh, I can do it right. We forgot about those. Well, I really should get back to work. So he goes back and sits at his desk and gets back to work. Nope, he goes and he finishes building Rake. And then every time I've heard Jim talk about Rake, the first thing he used to open it up with is, I'm really sorry, the last thing we needed was yet another build language, but I created it by accident. So let's look at some of the things he did. He sits down and he talks about the idea of, this is really easy to create in Ruby. And if you look at this from a Ruby perspective, it really is. If you come from an outside perspective and see Rake for the first time, it looks like a bunch of language keywords and built in language mechanisms. But truly, at its base, it's a method, right? It's a task method where we're sending in the name of the task and then we're sending some code along. And the code is along for the ride. We've seen this idea of code equals data. Giles talks about it where you just, it's just part of your method signature, right? This is passed along and sent off. And he writes out what we think we should do. And so they talk about, well, what about dependencies? Well, we can take advantage of Ruby's flexibility. And again, it's still pretty easy. And it looks like the language was built to handle this, but truly he's just taking advantage of some of the language functions and some of the features. And especially taking advantage of the lack of line noise. Only use parentheses where you need to while it comes out pretty damn nice looking, doesn't it? But we get to a certain point. And this is one of the things that I really find interesting about talking to Jim is Jim understands the idea of code that's written to be cute versus code that's written to be used. And we have an interesting problem here because if we create it like this, these methods are defined somewhere else. We're trying to play with the syntax, we're trying, or the context. We're trying to take this, package it up and send it somewhere else. And you can do some cute tricks. I've actually seen him do it. He sent me the file one time that you could do this with. But he made a conscious decision to make it just a little bit, let's say uglier. A little bit less natural maybe. But this is a really good decision because what he's doing is he's deciding, I'm gonna pass the task out. Because now the evaluator can trust me a little bit and say, I'll trust you that this is defined and this can be handled and we'll be able to go along our merry way. So we don't have to pre-define it and then call it and things like that. Because this is gonna be code used by developers. This is gonna be code used by people that are pretty, pretty smart. And we need to kind of help them understand where it's gonna be. And so understanding your audience is extremely important when you're talking about building a DSL. They needed something that I just always took for granted until again in that snowy Chicago day, Zach Tampson asked me one time, he's like, how do you think he did the description? I'm like, well, that's easy. It's just right. What the hell did he do? That's two methods. And the task knows that that's its description. Huh? Well, it turns out it's really simple. All he's doing is setting a variable and then when he defines the task, checking that variable and say, hey, is it there? Yeah, it is, okay, grab it. And that's where Zach came up with this idea where he called it spillover context. We're setting a context here in description and it's spilling over to the next thing. Because we look at it and we can know what's happening. But unlike the task where things are defined inside, there's an end keyword. And one of the hardest things to do in language design is understand where the end is, right? Understand where things stop occurring. And so this is one of those things that was, it was really cool when I looked back at it later on. I just always took it for granted because it always just sat there. You could put an enter after woot and it's not really gonna change the way it looks but it's really gonna make you scratch your head at that point. And people started complaining about namespaces and Jim went, it's Ruby, that's pretty easy. And now we have namespaces. And then we have really pretty looking rake files. That somebody coming in from another language looks at this and thinks, my God, this is elegant. Who here uses ant at their job or has used ant? Yeah, is this better? All those sharp pointing brackets you start hurting yourself. Act two, consistency. Or after, let's see, is this the one? Yeah, after Jeremy's talk, this is where Mr. T is gonna come and beat me up. So we have as many entitlements. What is this? You know, I said this talk is not about Rails but I'm gonna use Rails on the example. I'm a religious test-driven developer. I love playing ping pong with people. Have you ever paired program and played ping pong? It's a really cool game of Simon says when you start falling asleep about three in the afternoon, start doing this. First guy writes a test. The other guy writes the code to implement that test. The guy that wrote the test gets to look over your code and if your code's not covered by that test he gets to delete it. So if you put an extra if check in there because you know what the next test is gonna write he gets to take it out. And then you have to make him, through tests, write the code that you want him to write. And just the opposite, as you're writing the code, you're not gonna do a damn thing until he tells you to do it, just like Simon says. I'm not gonna take a step forward, he didn't tell me to. So when I look at this code, I don't wanna test that Rails works. I'm gonna assume that the core team are pretty good guys and they're gonna run their test before they check it in. So I don't wanna check that these associations are there, that they let me do builders off of them or any of this crap. What I wanna do is answer three questions because I, as a developer, when I wanna write this I have three jobs. One is I need to declare it. So one is I need to put in the fact that there is an association here. Number two, I need to put the correct association because I have been, more than one occasion, flipped has many versus has one and belongs to. So I need to make sure the damn thing's right. Number three, I need to make sure that on the entitlements table I have a residence ID call. There's convention over configuration, yes. But as developers, there are certain jobs we have to do. And I want somebody to tell me that that's the job I need to do. So I sit down and I take this. I wanna test drive it. So I start off and I write a test. This test that should have this association. And the first thing I do is I reflect on the association, make sure it's there. And people are gonna yell at me because yes I have more than one assert per test. This particular test I like to fail early because if I do have the correct key it's not gonna matter if my association's not there, blah blah blah, anyway. So I've chosen to put them in the same test and I go first, is the association there? Yes or no? Yes it is, it's great. Second, is the association correct? No it's not, go back and try again. All right, once that passes, go through and reflect on the primary key name, or reflect on the column names and make sure that the primary key is correct. Great, it works. I run it, it forces me to write the line, has many entitlements. Well, I need another one. So what do I do? I copy and paste, right? No, God no. I do what everybody does in tax unit and I go and I write a custom assertion. I refactor a couple things out and now I have my assert model as many and it's a resident model in its entitlements and that's nice and flowy, right? God no, that's pretty ugly. But it works. So then a good friend of mine, Stuart Holloway comes and we had a conference called eRubyCon last year. We're gonna have another one, don't worry, I'll advertise it later. And he says if I can write it in one line I wanna test it in one line. And so like every good developer, this started in itch and I thought, I need to go revisit those assertions and this is exactly what he was saying. If I declare it in one line, I wanna write it in one line. So I sat down and thought, how do I want it to look? I want it to look like this. I wanna declare what my entitlements are. I wanna test that those are there because this is what I want to do but I still wanted to make me ask those three questions, is it there, is it correct? Do I have the right column name on the other one? So I go through and I eventually end up evaluating it and I just build my association in a string and because it's Ruby, I can define it. ClassyVal is not as evil if you pass in underscore underscore file underscore underscore line because it does give you good debugging information. But that's not what I'm here to talk about. What I'm here to talk about is the fact that in the end what happens, I look at my code and I say here are my associations and I look at my test and say here are my associations. I wanted consistency. No actually I just wanted to prove that it can be done and give it to Stu but that's beside the point. But what I have now is consistency. What I have now is a model that looks pretty simple and a test that tells me that that's what I was trying to do. I'm not testing the associations. I say this because every time I give this there's always a hand that goes up and goes well you shouldn't be testing the framework. I'm not testing the framework. What I'm telling you is I'm playing with the language. I'm manipulating it around. This is something I can't do in Java. This is where we have these really ugly asserts that come in. I'm pointing at the screen like that's not doing it good. I have these asserts that don't look natural. They don't feel natural. Does natural mean English? No it does not. Dave Thomas had a really good blog post like this last week or week before where he talked about DSLs and he says you know if you're aiming for English you're probably missing the point. Aim for the domain. In this case my domain that I'm in is Rails. So I'm aiming to be consistent within Rails. Act three, business language. This story has a really kind of funny ending after all the build up but since it's proprietary code I have the agreement from the client that I can change the story and use it. So let's pretend we're in a just in time inventory system. We're in a factory that has just in time inventory. For each inventory item they have this language that's been established of how they deliver things. And we're handed this document and says here's the rules of what happens. And what you need to make sure is these deliveries do not occur at certain times and the deliveries do occur at certain times. We have to algorithmically go about and do this. In this particular case in this particular factory it's very highly regulated by the state, by federal and by the particular factory. They have their own rules as to when these happen. And so you look at the language and it's there. So Jim and I are working on this project together and we start working it out. And we create our objects, we have really nice OO design, and we start going to town. After a while we discover that they can actually be reused. We can actually start harnessing some of the others because some of these definitions actually mean combinations of others. And so this is Ruby, right? So we can start harnessing grabbing and or, ampersand, yeah, ampersand, or we can grab these things and start changing what their meanings are in this particular context and start chaining them together. That's really cool. It's not the whole DSL. But it was kind of fun, right? Because again, we can't do this in a language. And then we start looking and decide we're talking a lot about time. And this is where Jim and I came in and did the time DSL. Why? Because it was just as easy to create as it was to look for one. So we did six hours, we did four days, we did these kinds of things and put it in, not four days, it was already done, but the hours and minutes. And we wrote our tests. And we're writing out these tests and we're discovering that there's a lot of these edge cases that are happening, a lot of these boundary conditions that we're really not sure about. What happens here, what happens here? So we start a list, okay, let's keep a list, we'll make sure to ask the client about this one and this one and this one. And after a while we're like, you know, this is getting ridiculous. We've got a lot of these scattered about. So we're putting comments in the code and maybe we'll go through those and we won't forget. Yeah, that doesn't work so well either. So I say what I always say when I'm around, Jim, which is let's write a DSL. And so I'm like, what would it look like? What are we trying to do? We had refactored our code really, really nicely for us. For us, this made a lot of sense. I just hit that, didn't I? Anyway, for us this made a lot of sense. We knew what we were looking at, we knew that it should accept it, we knew it was today, we knew that these were not. But to the client he looks at this and he thinks, my God, I'm seeing commas, I'm seeing parentheses, I'm seeing exclamation points, what the hell does all this mean? So we try to create something that's a little bit more natural and we start talking about it. Like, what if we did something like this that we could put in front of the client and say, is this what you were talking about? And he could verify it. And we're like, oh, this is really cool, let's do this and we take it and we show the client and he goes, huh? And so we adjust some things and eventually we look at it and we go through it and we discover that we had to scrap the entire part of the project because we couldn't algorithmically solve the problem we were trying to solve. But what was nice is we were able to present these things to the client and say, here are a lot of these edge cases, these things that we're not thinking about. And eventually we had to backtrack and make it a human decision that happened. But I found the whole process was really interesting because we're actually taking it and putting it in front of the client. So another one I don't have code for and can't really do the full story but was a really interesting project was this one that was done where there was a company that had a marketing department that came up with these hare-brained ideas on how they would do things for their customers, okay? And so every so often you would do something. Say you were in a video store, okay? You ordered so many videos and you would get one free. Well, in that particular scenario, that was that. But in other scenarios, maybe on every Monday you get the third one free and then this would happen and so you started having these rules that would happen occur. And eventually all these rules were were a bunch of database calls. At the end of the day, this particular project was just nothing more than a series of database calls. So this team was parachuted in and I was on it for a very short period of time and they did something very fascinating which was talk to the client and figure out the two people in the entire company that had to communicate, an accountant and a DBA. And that communication's always smooth, right? No. My God, no. And we'd actually see they're talking to them about what they need and they'd start talking and it was literally like sitting one person down and having them speak French and the other one speak Russian because they had no idea what they were doing. And so we're trying to talk to them and figure out how we can do this because this is becoming a bottleneck. This is becoming really hard. And so what the team was able to do was basically create an ORM. But the ORM looked nothing like Hibernate. It looked nothing like Active Record. It looked like this company's language. And they could teach the programmer, the DBA, what a symbol meant. They could teach him what a string was and he knew where these things were. But they made a very important decision. They decided to make this a human-readable language and a human-writeable language. They decided to make it so that the DBA could write the language. But then what would happen is the accountant would come in and verify that it worked. And instead of signing off on a Word document that had a bunch of definitions and then making a transition of that into code and losing it out, they actually took, he actually was able to look at the executable code and say yes or no. It was a fascinating way of taking a language and molding it and getting it down to a business language. It's another really interesting part of, so we're gonna see what I'm doing on time and slide-wise here. Okay, still okay. This is a really interesting aspect of DSL and a very important thing to think about. And Dave Thomas wrote about this recently. But that is think about the domain, okay? Think about the fact that you're in rake and developers are gonna be using this. There's only so cute you have to be. We understand when you pass something out of a task. And if it's gonna give you much better integrity in the library in general, go with it. In the case of Rails, I'm not targeting English, I'm targeting Rails. So I'm targeting something that looks like, that looks like something people are used to. And then in the case of the business language, not this particular one, but the other one that I was talking about, you know, target the language that they're looking at, target the things they're doing. And I dropped my remote. That was smart. Good to have a distance wireless remote when you don't have anything. So one of the first resources I wanna point you guys to is an article that's currently, or it's not an article, but a video that's currently on InfoQ. It's Rich Kilmer. And he does better explanation than anybody and any of us could hopefully do from firsthand experience on building a DSL. He built one with the Air Force. And it's a fascinating story. And it was one of the most deflating moments as a speaker of my life. Because I went out to San Diego, or not San Diego, Silicon Valley. I always get to San, whatever. Santa Clara. Thank you. I always forget the last part of that. I go out there to talk about DSLs. I'm all stoked and excited. I sit down with Rich the night before I go to talk and he shows me this thing that he's done that he had just given a talk on that I missed. And I'm like, okay, I'm just gonna get on the flight and go home and forget what I did because he just totally showed up what he did. But this is a really good talk and he gives a really good example of what he's doing. So this is kind of a hand wavy kind of demonstration, but he goes into the details of what's there. So please go look at this video. The other resources, of course, I talked about Martin Fowler's DSL work in progress. And then we do know about a Pragmatic Programmers DSL book coming out that looks like it is making progress and gonna be out in beta. If you haven't read them, the Art of Unix Programming and Hackers and Painters by Paul Graham, excuse me. First one's by Eric Raymond. Second one's by Paul Graham. Make sure to read these. These really, are fundamental to what we do as developers and understanding the thought process that go on a lot of the software we use is really important. But in there they talk about many languages and then Paul Graham talks about why every language except Lisp sucks because you need to be able to mold and manipulate it. And it's actually a really interesting list because they'll start ranting about other languages. I've yet to see him rant about Ruby. Credits for a lot of this work. First of all, Jim Wierke and I have a lot of discussions about this and we'll probably have more arguments tonight about it. As he tells you why DSL's really just totally irrelevant. Paul Graham, Martin Feller's work. Jeremy who's sitting in the back. Zach Tampson from ThoughtWorks and Neil Ford. The four of us were working on a project together and formulated a lot of these ideas. So again, I'm not telling you guys any of this work as my own, I'm just kind of formulating and putting it together. And I can't leave without advertising my own little thing, which is the Rubycon. Gonna be in Columbus, Ohio. We're gonna tackle Enterprise Ruby. Everybody's running away from it in the Rails world. I'm running to it. Is that suicidal? God, I don't know. But I'm gonna put on a conference that talks about what are the big things we can do in Ruby? What are the technology things and what are the cultural things? So really interesting, gonna be really cheap. A lot of fun. One of my favorite things. What I hear, I forget. What I see, I remember. And what I do, I understand. So find a stupid excuse to create your own language. Find something you're doing, look at it and say, how can I make this prettier? What can I do? What can I play with? Don't do it in production tomorrow. Don't try to do it at your client the next day, necessarily. But find an itch and try to play with it because you're gonna learn a lot in doing this. Make yourself a calendar. Make yourself something. Try it, play with it. You'll learn a lot of Ruby. It's really cool. It's kind of like learning a foreign language. You learn way more English than you do the language the first time you do it. So you can find me way more often than I should be on Twitter. Of course, my blog on my company site. And thank you. I almost forgot now that everybody's trying to leave. Any questions? Comments? Tomatoes? Yeah, chairman. I actually really appreciate your treatment of the Rails testing here. Maybe that people always yell at me. You're testing the framework. You do that? You're testing Mr. TF? No. What I wanted to say is, the reason I would send Mr. TF would be if, like I was looking at some code the other day and someone had met a program to help her to include a module of validations where they only did it one time. All this effort to basically not, I mean it was cool but it was useless. All that effort to do something. Right. So you're not saving yourself any step to just creating more code complexity. And you see huge lists of metaprogrammed helpers and models and it looks cool but it's so slow and so clunky that. Right. If you're doing a metaprogrammed you're just going to say metaprogrammed versus, you know, it's kind of a rule of two or three. You know, go at it and then try it again. Yeah. Thank you. Appreciate that. So what you've done with the new language, I mean when you're talking about a DSL, is it essentially built on top of Ruby or, what do you end up with? Is it still just Ruby? You end up with XGB Ruby. The entire, and I must, sorry, I missed the point of that in discussing, but the coolest part about this is when you're in Antony and you're in Antler you have to solve problems that have always been solved before. And what I'm encouraging people to do is take the language and just twist it, mold it, manipulate it, see what you can do, but still stay within Ruby. You know, one of the things I hate to see is there's actually some demonstrations of DSLs out there even in Ruby where they take a first pass at something and regex replace a bunch of things and then use Ruby, because to me you're kind of outside. Now that's a controversial step that most people don't agree with necessarily, but in my mind I like to see when you just take advantage of that interpreter, take advantage of that language that's already there. So does that answer your question? I think so. I mean essentially you're still in Ruby if you abstract it at another level. Exactly. Jake. I gave a lot of examples of tests and in Dave Koms's post which you cited, he came out pretty strongly against R-spec. So I wondered if you shared those opinions about R-spec and what you're using yourself. Yeah, I actually like it and I think his argument was that perhaps it's English attempts are like forgetting the point that it's meant to be domain specific to testing. I would actually think things like Lord should are actually valid domain keywords. Right, there's a current argument out there as Jake pointed out where Dave Thomas and in the same blog post I'm referencing talks negatively about R-spec and the fact that it isn't as natural as some people say. But what I find interesting is actually, R-spec is a great example and give me a minute on this because one of my favorite moments that defined why I wanted to study this language further was at RubyConf 2005. We're sitting out on a porch and I'm sitting there with a guy by the name Aslak Helisoi and he pulls up in his laptop and he's like, what is it about testing that bugs you? What is it? And we start talking and Steve Baker had just come out with a first very rough version of R-spec based on a blog post from somebody about BDD. He goes, well this is Ruby, this is easy, we can do it. And the remnants of that no longer exist but Steve's inspiration has taken R-spec and just kind of propelled it and at that time they're talking, they're taking discussions from everybody there and it was a fascinating discussion because we're talking about things like, there were tests where I had different setups that I would wanna do setups that didn't necessarily apply to some of the tests. Well, I was missing this idea of context, testing it in this context, testing it in another. So for me, R-spec solidified that but you look at guys like Chad Fowler and you look at guys like Dave Thomas who openly say, don't necessarily get it but I don't think that's a bad thing. I like the fact that we have two testing frameworks out there. I like the fact that we're thinking about how to do things differently. I personally think the word should is a lot more natural. Chad actually likes test-specs. Yeah, absolutely, he does like test-specs. So there's parts of it that are going, there's parts of it that are good and bad and I think we're gonna ebb and flow back and forth but I think it's a really interesting discussion that's at least happening. Yes, can you talk more about the difference between internal DSL and internal external BSL? Yeah, I did. Can I talk more about the differences between internal and external BSL? It's very simple. An internal DSL is something where you take an existing language and you make use of its benefits. You really don't go outside. External DSL is where you're using a parser, you're using an interpreter, using something on the outside that comes in and messes with it. Now there is a little bit of a gray area there. So when I talk about taking a file and maybe Regex replacing spaces with dots so that you can then use a different syntax, that starts marching a gray line that I'm really not gonna stand on a soapbox and say personally, okay I'm gonna stand on a soapbox, dammit, can't stop myself from doing it. Personally I don't think that's an internal DSL. I think you've crossed the line. Some people don't think that's a line that's a big deal. But when you're using outside items to look at a file and translate and interpret it and then do something with it versus taking advantage of an existing interpreter that's already been written and using it, that's the internal. And Martin Fowler has this up on his website. In fact his initial, if you Google for Martin Fowler in domain specific languages you'll get his initial bleaky entry which was kind of shorter and sweeter and had that definition in it. Getting a lot of glare or someone seeing his hands, yes. Where is the trade-off or is there a trade-off? Can you avoid the time of the trade-off between simplicity over magic versus a DSL? And DSLs are beautiful but often when I see them I think I'm not the magic of this. Is there a trade-off between the magic of the DSL and the simplicity of the thing? Yes. And I cross that boundary all the time. There's a line that's been drawn in the sand and I go running past it. You're always gonna find that but you just have to get used to it. But it's a tool we're not used to having. So of course we're gonna overdo it. If you looked at the initial versions of Rails that came out there that did some amazing things but we look at them now and we laugh at the way they implement them. Why? Because we've learned since then. And everybody's done it. The old code that I found in Ruby that I really hated I look back on and say, why did I ever do that? Well I didn't know that this was not a good way to do things. Everything ran through method missing. So we're gonna learn what those boundaries are and go back and forth with them. Jim. I just wanted to comment on your question. For me, it depends on whether I'm doing API or DSL. The API is for a programmer. I try to narrow the size of simplicity. A DSL is for potentially a non-programmer and I don't care if there's magic in there. If it makes it easier for them. You're ready for yourself. I have a programmer. I go for the API. Does it need to be organic to the domain? Yes, I would. Also. I remember that when I wrote it. Is that the difference between magic and... Is that understandable in the domain? Does it need to go organic to the domain? Is it understandable in the domain? I think that's the idea that we're trying to get to. We're trying to get a more expressive idea out here. Another layer of abstraction that makes sense though. Not just one we're making up for no rhyme or reason. And I think that's where Dave disagrees with our spec. He thinks we're just in a lot of ways making some of the things up just to make them up. That's the line we have to figure out where that is. But yeah, it needs to be organic to the domain exact. Sir. One of the things that has always, to a certain degree, irritated me about rake is the notion of we're going to put white space where Ruby allows it, but we're in fact not idiomatic Ruby to have the white space there. I mean, you'll see in recent versions of Ruby it will complain about certain uses of passing parameters without the parentheses. And that tension has always, I mean, it seems as though the idioms for rake are in the opposite direction, primarily because we've all seen build files written in make and well, make is the one that comes to my mind first. But where the tasks and the dependencies are not great. No, and I get that, and it's interesting because actually my rule of thumb is always just to think about how these things are interrelated to me. But that's interesting to me, but I had an incredible talk to Jim about and discuss because I know he's been doing a lot of work to go to the 1.9. And I'm sure some of these things are being dealt with. But that's again part of that ebb and flow is where we're going to have some idioms that are there from rake and some that are there from Ruby and some that need to be there. And it's an internal DSL, so we're going to go back and forth. Josh. So, you know, Paul Graham's quote is, you know, they're really long. Yeah, exactly. Anybody who's done a lot of lists just events that are online who potentially are doing files in Macro or whatever facilities that they got there. And but that would come real quickly because as soon as you start playing on Macros, you're not programming in lists anymore. It's someone else's most undercoded and they know what you're doing. And probably whatever tool you're using to do your programming in lists right down to what you're doing too. Yeah, I've done that style of list coding agreement, so I don't know what the tool supports these days, et cetera. What do you see happening in Ruby with people building DSL teams that got a flow whatever style DSL building seems to still be Ruby-ish. But there are other forms of DSL that people play around with where you eventually leverage and you're not in a program in Ruby anymore in front of the tools follow up or... Right, so we're talking about programs, talking lists and the fact that they go back and forth and they end up creating their own language which is really hard to hand off to somebody and the tool supports just not necessarily there. I guess my answer to that is I think every list of programmers in Emacs they just build their own damn tools, right? But it's interesting because I don't know how I feel about that. Like I think we make a lot of language decisions based on tools and I think that's wrong. I came from the Java world and there's a lot of people who are afraid to leave Java because for a language like Ruby because my tool is no longer there. So I'm gonna purposely not let myself be more expressive because of this and I don't know where that's gonna take us personally. I think it's gonna be a problem at some point but I think I've also gone into places where they have Java code that has not been changed or done anything cute with and it still takes me forever to figure out what the hell they're doing anyway. Even though they're following the exact language rules and things like that. So I think any domain you go into you enter that risk anyway. If you have something that's more expressive you learn the domain. If it's done correctly you learn the language as you go too. I don't think there's anything wrong with flying without a net. Yeah and sometimes you do a good trade meeting with that but I think it's good to be conscious or at least aware of when you cross that line and I was curious to see if you had any insight into how we're going to change it and how that probably goes when it's happening. I wish I had insight into that and my insight right now is that keep a pair watching around and slap you when you go across a line because I go across it every single time. I always take it further than it should be. So I'm really kind of a bad person to ask about this but I think in exploring this we're gonna find what that definition is because personally I don't think we've decided where that is yet. But yeah it's something we need to be conscious of where you're trying to get too cute or trying to do too much. I got to say that I think R-SPEC processed that line just with the way you build matchers and it took me a really long time since staring at it and trying to figure out how that was actually working in the first place. Which is interesting because I love cheering opinions like that from guys like you who have experience with it and have a hard time with it because I've also trained some new developers in Ruby and Rails and teach them R-SPEC and it just kind of makes sense. You know where they're not bringing some of our preconceived notions. I think, I don't know. You know. It's not that I think exactly what you said it was you know what crazy metaphor you're currently doing and how all of that can be able to do these crazy matches like that. Very much so. When you talk to Dave, you talk to Aslak, you talk to any of those guys they'll fully admit the fact that they have crossed the line several times and come back and you know they've gone through those growing pains, definitely. Any others? Yes. Jeremy. You talked about community versus right though and that actually might be to your point. A lot of you yourselves are really optimized for reading. Yes. R-SPEC is really optimized for reading for sure and writing certain types of things but once you get the knowledge you have to really understand it and bring it in and that part it's not obvious but it's actually much harder. So. So yeah. Any other hands? Yes. There's been a lot of talk today about meta-programming. A lot of allusions to well we used to do it in some way now we're doing it in better ways but coming into it where do you start converting the movements? Oh. Oh. That's actually a great question and I wish there was more places to point here because we are still forming some of those opinions and yes, I'll let you talk in just a second. I have seen some books proposed that are starting to talk about the same things that we encountered in the Java world when Java was first starting. Everybody went out and ran out with it and started doing things but we didn't know what was the right way to do things. We had interfaces but how the hell did we use them? What were they supposed to be done? And eventually somebody comes out like Josh Block and goes, okay, effective Java, boom, let's draw the line in the sand. And I'm hoping some things are gonna start coming out like that. For right now talks like this, listening to Jeremy talk, reading Josh's blog, people like that are out there that are talking about it, watch what they do and follow what they do. We're gonna make mistakes. We're not at a place where I can give you definitive answers as this. And that's that. Jaws. I was just gonna say that as far as I can tell for this particular set of questions on Ruby, like how do you do metatrogramming and the nuts and bolts of it, the best two books are really Ruby Way, Household, and Ruby for Rails, but Play of the Black, the one that Jeremy mentioned. And it really comes down to like the final four chapters in Ruby for Rails will give you like, I don't know, you can just pack the whole thing in there, but Ruby doesn't have lots of room for that. Yeah, and that's a good point. There's a lot of documentation on how to do it now that we didn't have before. In fact, even, I thought that was advanced, that's not, that's Ajax. Oh, there it is. Advanced Rails, the O'Reilly one. Has one of the opening chapters talks about metaprogram. It has a really good description about the object model and how it works. How Fulton's book is fantastic for that. Actually, if you're gonna do any kind of Ruby, you need to have the pickaxe on how Fulton's book next to you anyway. But, you know, those are gonna tell you how to do it. But what is the right way? What are, you know, what's the things to do? I don't know, you know, open some of Jim's libraries, open up FlexMock, open up Builder, open up Rake, open up some of the other gems. Look at Jay's adhesion stuff. You know, start seeing how some of these people are doing it and talk to them. Jay. I want to bring up the R-spec thing again, because I think it covers an abstract yet important thing about DSLs in general. And that's like the ambiguity in implementation. And I think Rails is even more of an example than R-spec of like crazy magic that's going on and some of the active record stuff. Yeah, we never question that. We take the macros and stuff for granted because we like them. And I think R-spec is like a red herring for this whole like DSL topic. Right. Well, because R-spec in this lifetime is where Rails was, if you look at, say, 0.13. Okay, they'd already gone through a lot of revisions, they'd already gone through some cleanup. And maybe that's a bad example, exactly word for word. But, you know, these guys got a later start and they started doing some of these things. And they're looking at Rails and looking at some of these practices, but they're doing a lot more meta-program than some of the others. Trying to be a lot more cute with some of the things they're doing. And in that, they're getting into some holes and getting into some places. But if you started playing with R-spec early on, our company started using it at 0.7 and we're using it to this day, I really like where it's going and I like the progression that's done. But yeah, Rails has been doing a lot of this stuff too and they hung themselves in a lot of places. And if you notice, performance is getting better and better and better with Rails as we go along because I think they're starting to look at some of these things and look at some of these items that we're doing. So, all right, any more questions, please find me. Let's let everybody else go home. Thank you.