 Hi, I am Mansi Shah, currently I am a student at Geek school, today I am going to talk about compiling your own domain specific language to JavaScript. So, let us start by understanding what a domain specific language is, a domain specific language is a language that is specialized to perform a particular application, it is different from a general purpose language in the way that it has domain specific features and characteristics. Let us look at an example of a domain specific language, say you were to teach programming to a kid by giving them a subset language with predefined actions to control say maybe a Godzilla killing robo, you can define behaviors using the predefined actions to control the behavior, one of the behaviors could be behavior walk, which is performed when destination is ahead and the actions you perform are move your left foot, move your right foot. Another behavior can be behavior attack, which is performed when Godzilla is in view and actions to be performed could be fire laser eyes, launch arm rockets, so if you were to translate this to JavaScript, it would translate like this, we just define functions walk in attack which call the methods for the leg movements and the attack and then we run the program in a loop where it says while you see the destination keep walking, also there is an inner loop which says if Godzilla is in view attack, this translates so simply to JavaScript, there cells make sense right, this is just a warm up to domain specific languages. Let us see how we would have a workflow to compare a domain specific language to a target language, we pass the domain specific language to a parser, we generate the abstract syntax tree for it, we pass it to a generator and we generate the target language from it. Let us look at another example of a domain specific language that employs this particular workflow, how about Lisp like JavaScript, Lispy script, so this is a code snippet in Lispy script, it looks very familiar to JavaScript only that there are lot of parenthesis here, so the statements inside parenthesis are expression, we have three main expressions in the function in the body, one is a variable declaration, the next is a function declaration and the last one is a call to the function that we declared earlier, let us see how this translates to JavaScript, it is pretty straight forward right, we just declare a variable, do the declaration and that is how it looks like in JavaScript, so we are talking about Lispy script, let us understand what Lisp is, Lisp is a family of languages where almost everything is an expression that evaluates to value, exceptions are like statements like variable declaration or function declaration statements that have an effect in the program but do not evaluate to value, the beauty of Lisp is that the language itself is the AST, so what is an AST? An abstract syntax tree is a tree like representation of the program, ES tree, ECMA script tree is one form of JavaScript ESC, so let us look at the ES tree for a code snippet in JavaScript like this, variable declaration A is 5 log it to console, we start with the root node program which is how all of the JavaScript ES trees start with, we have a variable declaration with the variable declarator which is A which is initialized to the value 5, we have an expression statement which is a call expression where the call E is consoled at log and the argument rA, so this is how our ES tree would look like, so let us see how we would use this ES tree to compile a domain specific language to JavaScript, we would take Lispy script which is the domain specific language in question here, we parse it using a parser, we generate the ES tree out of it and we use a generator like ES code to compile it to JavaScript, let us see this in action, this is a very simple function declaration in Lispy script, it starts with the keyword function which signifies that it is a function declaration, it has an identifier, it takes parameter x and all the other expressions after the parameters are considered to be the function body, if you notice everything is an expression here, everything is comprised inside parenthesis, also there is no return keyword, so the way Lisp works is the last evaluated expression in a function body is returned as a return value of the function, so the ES tree for this particular Lispy script code would look like, we start with program which has a function declaration statement where the id is square, the parameters are x and the body is a block statement and since we just had one expression in the body, that is I data is also the return statement which is a binary expression where the operator is a multiplier and the left and right operating are x and x, the generator expression just are set only if it were a generator function or an expression, so this is what the Lispy script code would compile to in JavaScript, pretty straightforward, it says function square takes parameter x returns x into x, so let us go into the inner workings of this whole workflow, the parser and the generator part of it, we use a recursive descent parser, a recursive descent parser is a top down approach parser where a set of parsers are tried recursively to try and consume the program string, so if the a part is consumed, the parser would return the consumed representation of the string and the rest of the string and if it is not consumed, it would return null and try the other parsers, so when we see a set of parsers, it will mean elementary parsers like null parser, Boolean parser, number parser, etc. and would build up to more complex parsers like function parser, variable declaration parser which are built up of the elementary parsers, so here we have the program, variable a is equal to 5 Lispy script program which is comprised in the SRC string and this is a null parser, so what we do here is, we try to match the string against this regular expression and see if it matches, if it does not match it simply returns null and it would go on to try another parser, if it does match we slice it out of the program string and then we return the representation of the value that is type is literal and the value is null, so if it were a number parser it would use another regular expression to see if it is a number and it would return something like type literal and value is a number which is the matched part of it, so that was the parser, now let us look at the generator of part of it, we use a node module called escode gen to generate JavaScript out of the es tree, we require the generate function of the escode gen package and we pass the program to the parser and get the ast out of it and then the ast is passed to the generate function which gives us a JavaScript, so you see you understand how the workflow goes, you compile the domain specific language and parse it and you try to get the tree out of it and then you pass it to a generator and get the target language, why would you need a DSL though? You can have a domain specific language which has domain specific features like something of the sort that we saw in the first example, you can do some language extension by adding features to existing language that does not supported out of the box, like say you want to add macros to a language like JavaScript, so that is what we intend to do with list p script, also you could do some code optimization to make the code compile faster, so we are talking about list macros right, what are list macros, list macros are way to transform code on the fly, the macro during macro expansion the expressions pass to the macro function are computed and inserted into the program as code like it were originally present in the program, so when the compiler interpreter sees the code it executes it immediately, so you see how it looks at it like it were originally a part of the program that is the purpose of using macros, you can use macros to do some like you know generate your own special forms and structs in the language, let us look at some examples of macros, we have a do macro, the purpose of do macro is to take a variable number of expressions as arguments and it returns an anonymous function which comprises the expressions as its function body and then it calls it immediately, so if you were to make a call to the do macro with the expressions where a five and another call to a, it would look like this in JavaScript, we are using arrow function expressions to do anonymous functions here, it takes no parameters and has the same the translated code in JavaScript as a function body which is variable a is your find return a and if you notice it is called immediately, we are also using the rest element or the spread element operator here, so this is just an array of a variable number of arguments at a pass to the function, let us look at another macro that is a when macro, so the when macro takes one condition and then a variable number of arguments, it tests if the condition is true or not and if it is true then it passes the arguments to the do macro, so if you were to do a when macro call using a condition true and an expression console.log is true, it would translate to JavaScript as if true console.log is true, so you see how the expressions that are passed to the macro function are not compiled or executed immediately, they are inserted into the program in a way that it will compile later on, this is a very useful feature to have in a language, so that is why you could have something of a sort like compiling your own domain specific language to add such kind of extensions to an existing language, you could make your own language and that is how you could like use this particular workflow to do it, if you wish to check out Lispy script or want to know more about domain specific languages and macros, you could check out the project at these links and open to questions now. Hi, what feature in Lisp do you think JavaScript could have? Sadi, Sadi. What features from Lisp? Are useful to have in JavaScript? So like I'm just doing this Lispy script project as like a project for my Geek School period to learn more about how these things work, obviously like I'm just learning more stuff about Lisp, I guess the expressions part of it, I'm trying to, you could actually add monads and all of that to Lispy script, you know, using the macros, so yeah, that is what I intend to do with Lispy script and you could answer features in JavaScript. Okay, thank you. Questions? No? Thank you. Thank you Mansi.