 Thanks for coming to my presentation. My name is Martin Thiele. I work as a software developer for Lear Corporation in Munich in Germany. And Lear is actually an automotive software supplier. It's a US-based company, headquarters in Southfield in Michigan. And Lear is manufacturing seeds and electronic and electrical equipment for vehicles. And we are not building the Learjet. In this talk, I want to first tell you a little bit about one of our current projects where we generate code for a vehicle using Ruby. And we do this with a small code generation framework called Arjen. And I will talk about Arjen in the second part of my presentation. And Arjen is really also about DSLs. And in the third part of my presentation, I will tell you about a new model editor, which is called Concrete, which is a web-based editor for DSLs. So in our current project, we are building an electronic control unit for the upcoming BMW 1 and 3 series. This is the current 3 series, so I cannot show you the new one right now. This control unit, we also call it an ECU, electronic control unit, this one controls many things on the outer part of the car, like the front lights, the door locks, the ride bar, car entry, keyless entry, remote control, mirrors, a couple of things. So it's relatively much. This is one of our test setups. The control unit is lying on the table, the white box. It's about that size. It has 10 connectors going up to the rack. We have mounted most of the parts which it controls on the rack. So that's what we use for testing. And you can see it's really a big one. It's really one of the largest of its class, of this class of so-called body control units, because they control the parts on the outer body of the car. The hardware we are using here is a 32-bit processor, running at about 100 megahertz. It has 128 kilobytes of RAM, about 2 megabyte of flash, and a lot of IOs. Software is written in C and C++. Now let's take a look inside. This is the very basic software architecture of this ECU. So on the upper layer, we have application components, like for the light, the ride bar, central locking car access, and so on. And on the lower level, we have a basic software infrastructure platform, which has the operating system, communication stacks, persistence layer for writing data to the e-square problem or to flash, diagnostics, error logging, and so on. And this basic software platform is not just static or very generic, but it's tailored to the needs of the application. So what we do is we look at the application components, and we generate code for the basic software. We don't generate the whole basic software, but we generate parts of it. We generate very optimized structures and code. So that we can save resources. And this is actually a very commonly used practice in automotive software development to generate parts of the basic software. Besides the challenge that this is a really big ECU, we had another one, which is that we were one of the first to adopt a new automotive software standard called AutoSAR. And what this standard actually does is it specifies that there should be a description language for software components. It specifies an XML format for describing software components. So every software component is described by a little XML document. And further on, it specifies that there should be a middleware layer here, which is also generated. And it defines the API of the basic software platform. The idea is to make software reusable across different platforms, renders, and so on. So we generate code. And we actually generate code for two reasons. One is for resource constraints, because of the resource constraints. And the other one is because of the standard, because the standard really prescribes code generation. So we need this code generation tool. And I've actually been working on tools in the context of AutoSAR since 2004, when I started at BMW CAR-IT. And at that time, we were building these tools based on Eclipse and the Eclipse and Java-based modeling framework. And that was the time when I started working on Arjen. And what I did was I took the most important features of this Java framework and implemented them in Ruby. At that time, it was just a play project. But then in 2007, when we started this project, I was hired as the software architect because of my background with AutoSAR. And we started to describe all these software components. So we tried to make these descriptions. And we found very soon that the tools we had at that time were not really sufficient for the job, even not the commercial tools and not the tool we had created by ourselves before. And the point was that the tools did not really support collaboration. And if a tool doesn't support it, then it's very hard to do it on an XML level because it's hard to merge them. It's hard to div them, and so on. I think you all know this. So what I did was I took Ruby and my Arjen framework and built a new little tool called Progma. And created a little textual DSL for basically doing what these XML descriptions do, but in a very stripped down way so that they are just focused on this particular project. And here's an example. So this little example says there is a software component called Viper Control. It has two ports. And there are different kinds of ports in AutoSAR. You can just exchange data or you can provide operations for RPC, kind of an RPC. And there's a little bit of data type definition here. So this is just a very, very, very small example. But these 20 lines of Progma DSL correspond to 180 lines of XML in the standard. So you can think you can imagine that this helps a lot. And right now we are having about, in this project, we are having about 100 software components, several hundred interfaces, more than 2,000 signals going over these interfaces. So I would say that without this little Ruby tool, it would have been very hard to do this project. And actually, I do think that Ruby and the fact that it makes or can make programming enjoyable and very effective really was a blood and important role in bringing this tool to life at all. Because if I had told people in the beginning of the project that we need some time and people to create a new tool, it would probably not exist. So I prototyped this tool while I was working as a software architect. And suddenly it was there and people got convinced. And now it's a very important part of our project. So let's take a closer look at the tool. What it actually does is it reads in the textual DSL and it outputs either the code or the standard XML because we need that for talking to our customer. Can also go the other way around. This is a command line tool integrated into a build process. It just runs before the compiler. Now going one level deeper, what we actually do here is we have a parser which reads in the textual DSL and we create a model. And the first model is something like a pragmatic model because it's a simple model. It's just focusing on this particular project. So it doesn't have all these data we don't need. And from that, we do a transformation of the model to either a model which is close to the output we want to generate. That's actually a best practice of code generation. As far as I know that you create a model which is close in structure so that the templates get simpler. And for outputting the XML, we transform this model in the big model by doing a lot of things by convention, automations, and so on. And then we serialize this model to XML. So what we need here is we need to be able to represent models, transform models, generate code. And generally speaking, we need to deal with DSLs. And that's exactly what the Arjen tool is about. So Arjen is available on GitHub. It's a gem. It's rather small. It has basically no dependencies in the causal. I would say it's really lightweight and very flexible. First of all, I want to give you a little impression of what I mean when I talk about a model. And here's a simple example. So the right box is an object, which is an instance of class state machine. It has an instance where we will call name, value is air condition. Here's another object, which is an instance of class state. It belongs to the state machine, so it's linked to the state machine. It has a name called on. There's another one called off. And here's another object, which is an instance of transition. It's linked in from the on state, so it's an outgoing transition. And it has a reference to off. So it's basically saying there is a transition from on to off. The right boxes are the model, but they are basically just Ruby objects with references. We have some model-specific naming here. So we call the object a model element, instance variables, which hold a primitive value. That's what we call an attribute. And the references are called references. There are different types of references. So we have references which can point to one thing, like the target of a transition. And we have references which can point to many things, like the outgoing transitions of a state. And we have references which are bidirectional, which basically means that if you put a state into the state machine, the state machine will automatically be referenced from the state. That's very handy if you want to navigate the model in both directions. So in order to build this model up, we need the classes and the accessor methods. And to do this, there is a little internal DSL in Arjen, which is called the metamodel DSL. And I will tell you in a minute what I mean with metamodel, because it's a bit confusing. This example probably reminds you of Active Record and it's actually inspired by Active Record. So I say I have a state machine, which is a subclass of MMBase. It has an attribute called name, and it has a type, which is string. The other classes, a state, also has a name and the transition has a reference to a state. There are two more references. So the state has many transitions and the state machine has many states. And in this case, this is a bidirectional reference. So by using this command, I'm saying that it should automatically have the link back and maintain this. Then by putting a module around this, we group this up and by using this module extension, we're telling Arjen that this should be a package of classes used for building models. Now what these metamodel commands do is they create the accessor methods. And the accessor methods are not just accessor methods, like if you write attribute, accessor and Ruby, but they do type checking because we have specified the types and this is important because otherwise the model would not be consistent. They do type checking and they handle this opposite reference thing. So if there's an opposite reference and you hook one element in another, it builds up the reverse reference automatically. That's very handy. What I want to do now is I want to focus more on DSLs. If you want to know about how to do model transformation and code generation, you can check out Arjen. There's plenty of information and documentation on the web. Regarding DSLs, generally speaking, DSL consists of an abstract syntax and a concrete syntax. You can think of it like a grammar of a past language and the syntactic sugar between the elements which form the syntax tree elements. So one is what's the content and the other one is how the content looks. Abstract syntax and concrete syntax. And what we have here is basically the abstract syntax of a little language, a language which talks about state machines. So we say we can have a state machine, it can have states, they can be linked and so on. In order to make this information readable by tools, if we want to build tools which pass the language or which create an editor for this language, this has to be machine readable. Now we can read it, but it's not machine readable if there's nothing more. And that's why these DSL commands capture meta information. They just capture what you see. So they capture the name and the type, for example. Or they capture, this is a too many transition. They just remember this. And so when you have this description like this and you load it up in Ruby, it will of course create the class objects. It will create the accessor methods, but at the same time it will capture the meta information. So now we have all this information about the different kinds of references, attributes and so on, but still it's not really accessible in a nice way. And that's why there is another model which can be accessed by calling a method called ecore. So you can call ecore on a class, on a Ruby class object, and you will get a new object which is describing this class. So for example, if you call it on the state machine object, you will get here and this class and this model element will tell, okay, this is named state machine and it has child elements for each reference. So you can look up the references. It will have, I think in this case, two references. You can check the type of the reference, the name of the reference, if it's bi-directional, non-bi-directional and so on. So what we have on the right-hand side is a model which describes the meta information. And that's why it's called the meta model. And you can think of it like the grammar of a parser-based language. And it actually describes how a valid model can look. And one more thing which is quite important is that this kind of meta model is compliant with the eclipse world. So the eclipse modeling framework is quite a standard in the modeling community. So you have a good chance that you get meta models which are compliant to this. And that's what we had for our programmer tool. We get the meta model from the standard. So we just get the XML instantiated in Ruby and then we are on the right-hand side here. And then Arjen comes with a little generator which takes the meta model and puts out the Ruby representation. Then we add this to our tool and when we read it in we have the classes. When we instantiate to the classes, we end up with a model which is compliant to the standard. And that's pretty nice. Now that we have this meta information, we can do more nice things. And one of this is Arjen comes with a thing called the model builder. And when you give the model builder the module holding all this meta information then it knows the language. It knows the abstract syntax of the language. It doesn't know the concrete syntax because we've not specified it but it just assumes a default concrete syntax. And now it creates an internal Ruby DSL for you. So what you can write now is something like this. There's a state machine called air condition, has a state called on, a transition to off and the state called off. So you get an internal Ruby DSL without any effort just specifying the abstract syntax. And when the model builder executes it will just create what we had before. And then there's a counterpart of it which is the model serializer and it turns it back. So you can run trip it. That's pretty nice. We are using this form for our unit tests. If we need models we can just build them in line in a little Ruby test file. So it's quite useful. But this is an internal DSL and there are cases when you don't want to expose an internal DSL to the users on the web because of security reasons because you don't want to expose the users to Ruby error messages or just because you want to give the user more guidance. And that's exactly where concrete comes in. So concrete is also available on GitHub. It's a gem. You can download it from Gemcutter. Right now it's based on Prototyping's Cryptculus and it's best used with Firefox and Chrome. And the idea of concrete is to have a generic editor which is set up for any specific DSL by telling it the abstract syntax as we just saw before, meta-model like this and the concrete syntax is defined by HTML and CSS. So you can define what your language elements should look like. So here is an example. So this is the meta-model we just saw. And concrete is written in JavaScript and for it to understand the meta-model, the meta-model has to be transformed into JSON. And there's actually a converter which comes with concrete. And I've just written this little script which makes use of the converter. The converter basically takes the meta-model, so on the root module just called ecore, that's the meta information, put it into the transformer and out comes the JSON. And I will just do it. So pipe this through this little tool and here's the same information in JSON format and now it's readable for concrete. Now take this and here is a very simple a minimal setup of concrete. So this is a static HTML page. I'm including prototype, script calculus and concrete and down here the editor is actually instantiated, hooked into the browser events and so on. Now I will just put the meta information here to make it accessible to the JavaScript. Now when we open this up in the browser, here's the Richard and it knows the language. So we can create a state machine, call it air condition, create a state called on, another state called off and create a transition from on to off. So this is the same example with a web-based editor. Now this is using the default concrete syntax because we have not specified any concrete syntax. So let's change this. Here's a version of this where I have added this little snippet of HTML and what it does is basically it says that it applies to the class state. So whenever it renders the class state it should use this little piece of HTML and there is of course some style sheet just telling it how a state should look like and now open this up and what I can do now is I can just copy this model and internally the model is represented as JSON. It has a clipboard and in this example the clipboard is just visualized. It's just for demonstration purpose. So I can take the stuff from the clipboard, put it in here, oops, that's the wrong one, put it in here and here's the same language with a different concrete syntax for state. So I have just changed the little snippet for state and still all the editing commands work like you can copy and paste this, you can rename this to stand by, maybe create a state called stand by and then from on I won't be able to go to stand by. Right, so here's how it works. This is a summary. So concrete is a JavaScript program. It runs in the browser and it gets the abstract syntax definition by means of the metamodel in JSON plus optional extra constraints written in JavaScript. So the metamodel cannot express all the constraints because it's EMF compliant or it has to be restricted of course so if you need extra constraints you can add them using JavaScript. This goes into the constraint checker and the autocompleter. On the other hand the concrete syntax is added by HTML and CSS. It's optional and the model by itself in the tool itself it's represented in the DOM right now and if you exchange the model this is done by JSON so you can get the JSON from the widget or you can put the JSON in the widget. So this is just a widget. You can basically integrate it everywhere but sometimes you want to work on files for example and that's why concrete comes with a Ruby based backend for accessing files and I've created a little bit more fancy editor which is a composition of two of these widgets. On the left hand side there is something for an index and on the right hand side that's where the model is actually represented. And what the backend does is it just takes the JSON converts it to an Argent model so you can work on it from Ruby it takes the meta model converts it to JSON puts it up to the browser and so on. So you can tailor this to your own language and all you would have to do is you have to provide the meta model, the HTML and the CSS and you have to provide code which reads your file you have to provide the parser and the serializer if you use the model builder and the model serializer we've just seen before you don't have to do anything you can use this syntax if you like. Now here's an example of this one this is actually also available on GitHub it's an example but it's quite useful because it is a concrete based front end to the language for defining the abstract syntax. So it's a rep-based editor for the internal Ruby DSL and it's quite small it's just 12 kilobyte in size because it really makes use of all what's supplied by concrete. So here's an example. Go here. So this is a bigger meta model. This is the internal meta model DSL we've seen before but it's a bigger meta model, it's a bigger language. Now let's edit this one in the browser. So I will just open a shell. You can install mmedit as a gem. I've done this already and I will just point it to the file containing the Ruby code and it will spin up a web brick in this case and then you can connect to localhost. So here's the editor. On the left hand side there is an index view so you see the classes and the packages and subclasses in this thing and when you click it, this module opens up on the right hand side. So this again is the default concrete syntax and the language in this case is this EMF compatible meta model language. That's what it's actually called E-core that's why the commands are E-class, E-package. So this is M eclipse compliant. Now this one comes with three different concrete syntaxes so just for testing we can switch this to a table layout. It looks like this and can copy and paste this attribute, for example, rename it and save it and then it's here. This one deleted reload and it's gone. So that's how you access the file and then there's another layout which is the box layout which is a bit more convenient. Maybe it looks like this. The editor supports collapsing so you can just collapse it, expand it using keyboard commands. You can visualize the targets of references by just hovering over it. You can jump there like this. There's a little search and replace tool if you want to change the model for example, change the name attribute or find the name attribute, find things named not. Ah, here it is. Okay, this is this one, not. And then there is a little thing like an open, a little finder for which finds all the model elements by index so this is also for really large models. If you have indexed models you don't show all the model on the right-hand side but just one module of the model and you can find all the models by just using this one so it will find the elements in the index and then you can jump there. Okay, so what you actually see here is the metamodel and the abstract syntax of the language of my last example and my last example is an online registration platform. I'm doing triathlon, I'm in triathlon club we are organizing triathlon events we have neighboring clubs which also organize triathlon events and I have for quite a while a platform for doing all these online registrations and it's quite a bit of work whenever some organization changes we have to change the online registration so I want the organizers to really be able to customize their online registrations by themselves and to do this I want to have a little domain-specific language which I expose to them on the web in a Rails application and this is actually the abstract syntax of the language so I want to be able to talk about data items which I collect from people they have a name, a type that can be constraints attached to a data item then I want to have pages so they can click through pages a page has a content element has content elements a content element can be just a text or a data input element text input elements or drop-down input radio input, checkbox input, date picker input and the pages are linked with each other so it's a successor and a predecessor page there's a guard condition for a page and then the page should show up and there can be constraints defined with each page so before leaving the page a couple of constraints have to be fulfilled and the users will get a message if the constraint is not matched okay, so that's the little language did I, no this is, explain the expression language this is the expression language expression is either a simple expression like equals or empty or less than and there are composite expressions built up of the simple expressions like an end expression or expression all of them are expressions so you can think of this as a UMA class diagram basically it's quite similar again this is the EMF way of specifying these metamodels okay, so now what I did was I converted this to JSON put it into a little Rails application and now let's start it so this is just a very simple example here are my registrations I have one currently and I want to create a new one so now what I did is I embedded the concrete editor Richard into a Rails view so the active record which is below this basically has just two fields it has the name, something new triathlon competition and it has the whole model which I'm going to specify now so I want a data item first name which is a string another one which is the last name also a string and another one which is the date of birth which is a date in my language these types are basically what you can do in Rails but it's just an example now let's create a page this is the personal data and I want a text input field first name which is this one copy and paste it last name for the date of birth I use a date picker input for my language like this now another page I want a page for the users to select the race type choose race type I don't have the race type yet so I create another data element called race type which is just a string but my little language works like this that if you want to have a drop-down box you attach a constraint to this and it's actually a one-off constraint and you just specify the possible values so in this case I can choose between the Olympic distance and the sprint distance like this and then add a drop-down field here race type like this there's a successor reference you get autocompletion on the possible references so the next one is the choose race type you can also visualize it here okay that's very simple now create it and now what it does is it has the JSON it puts the JSON as a string into the active record so the active record only has two fields name and JSON strings now I want to try it so I've written Ruby code to make use of this model it will just look at the model create a database table with the columns for each data item and it will render the pages and provide all the logic for stepping through the pages but this has nothing to do with concrete by itself concrete just supplies the data of the model so now let's try it so here is the first page next page so maybe I want to have another field here let's create another field data item called t-shirt because in most of the races you get a shirt which is also a string and I will just copy this and I have s m l and let's put a drop down box here t-shirt size so now we have the t-shirt size now I will cheat a little bit and use the one which I've already prepared it's even a bit bigger there is one more page and after choosing the race type there are two pages which follow up it's either the page which says registration is complete or if you go the Olympic distance you have to have a license and if you don't have a license and here are some constraint checks saying if you don't have a DTU license then you have to buy a one-day license and it doesn't make sense to do both so that's a complete example so I take the Olympic now I don't have one, try to go on it doesn't work, this is my constraint check so I choose the one-day license and I'm done so summarizing with concrete you get a way to expose your DSL in a safe way to your customers on the web you get auto-completion constraint checking you can have nearly whatever syntax you like by just using any HTML trick it's just a simple widget, you can embed it everywhere where you can use JSON by using Arjen you can have a Ruby back end to it so if you don't want to deal with JSON you just read in the JSON and you have a model in Ruby so you can work with the model check the model so and this is not Rails specific so it's really using not much of Rails you can use it with Sinatra with any application you can think of so well, that's it if you're interested, you can check out concreteeditor.org the examples are online you don't have to install anything, you can check out the online registration example which I just showed you you can check out some other examples, documentation is online it points to GitHub where you find the source code both of concrete and the examples so that's all thank you