 Could I get the USB for this? Morning, everybody. I'm Suhas. And today we'll be speaking about metaprogramming. And hopefully we'll go into an enlightening journey with the help of ECMAScript 6. That's me on Twitter. The slides, I've put up these slides, linked to the slides on my Twitter page right now. So you can follow me on Twitter and look these slides up. And I'll be posting some code as well tonight, right? So a couple of days back, I had this rather ambitious idea. And I told myself that I'm going to live code the entire presentation. However unadvisable that may seem. And I ran into a, yeah, the moment I thought of that idea, it seemed great in my head. And I was all excited, right? I'm going to live code the presentation. The audience is going to be, wow, and all that. So I decided that I'm going to download the source of spider monkey and build it on my Windows 10 machine. Some people are laughing there. They got it. So once I downloaded the source, I have to go through the entire build process. I have to configure. I have to make it, and all that. The moment I configured it, I ran into this weird error. It said import error, no module named 6.moves. What? So for those of, thankfully, I'm a little bit aware of the Python ecosystem. And I figured that out that it was a Python error. And it said, no module named 6.moves means there is no module called 6. It had a good debug message. And then I went to my default Python shell. Did a pip install 6. And then it was all good. I went to the Python console. I did import 6.moves. And it imported. It worked. And then I built it again. And then the same error again. I imported a no module named 6.moves. That's, start having a very bad day. And that's the problem with the software ecosystem today. There is a lot of complexity involved. And why this and metaprogramming? We'll see. Before we go into metaprogramming, I want to talk about programming first. And the image that you see behind us, the Manchester small scale experimental machine, all the way back in the 1940s. And this was the first stored program computer. So the stored program computer is basically either a one Noiman or a Harvard architecture computer. Basically means there is an instruction set and the data both stored. So it's a stored program computer. The instruction reads from the data and then computes. And then there is some kind of a result. And Tom Kilburn was probably the first stored program programmer. And programming has come a long way since then. From operating on data itself, we've started to do much more complex things. We've started to, we have all these design patterns now. We have bigger machines. We have very, very complex architectures. And we are solving great world problems today. And that requires a lot of ideologies and a lot of philosophies from a programming perspective. And metaprogramming is not the only answer. It is one of the answers. And we'll see how that will help us tackle complexity today. We'll see how that will help write cool programs. So one of the problem with the software is people themselves. So people have different ideas. People tend to code differently. People tend to think differently. People tend to write differently. And so for example, this, the slides that I'm presenting right now is from reveal.js. I think a lot of JavaScript people use reveal.js to present their slides. So that's one kind of complexity which the lines of code for this presentation itself is around running into 1,800 to 1,000 lines of code. So that kind of complexity is there and people tend to think differently. Let me show you how people think differently. This image behind is the Google auto-suggest. So a good indicator, Google auto-suggest is a good indicator of how people think differently in different regions. So when you start typing into the Google search engine, what Google does is see what kind of things are people searching around and then they suggest you that. So let me show you a, so Google has Google.co.uk, Google.co.au and so on and so on and the auto-suggest results for each of them are different. So let me show you as quick. So what we've built here is a little software that scrapes off of Google's content and tells you what people are thinking in these different regions. So when I type in how to in Google, people in India want to know how to kiss, people in the UK want to know how to make pancakes and people in the US wants to know how to tie a tie. People in Singapore want to download a YouTube video and those are the kind of things that people think in these different regions. Let me click a few more things. How can you, so India for some weird reason, India wants to make a numbered list. I don't know what Indians are thinking. So how do I know, he loves me, how do I renew my passport? We have different priorities in life, all of us. So at Grammar we've done a couple of demos like these and a lot of principles behind that is involved, involves a lot of complexity. And this here is a simple code but you start scaling up, you start putting in more constraints, you start putting in more complexity into the system and let's go to another demo. So this is a recruiter search. Scrapes all of GitHub profiles in a particular region and tells you what the network looks like. The people in the center are more connected with more repose on GitHub and usually better to recruit. You want the people in the center if you're recruiting and you can filter by the language and all of that. So the point I'm trying to make here is there is a lot of constraints involved again in software. There's a lot of logic involved. One more example that I want to point out is Prime Minister's speech, the ex-Prime Minister. He did speak a lot contrary to popular opinion. He gave around 1,200 speeches and in a lot of locations in a lot of places. So these kind of visualizations and these kind of programming aspects that we have involve coding, right? And people tend to think differently and what's the next problem? Complexity, what's the next problem? Ecosystem, so that's the problem we are facing today. People, complexity and ecosystems and how do we tackle this? How do we write better code? And that's the kind of journey that we want to take and metaprogramming, I'm sure all of you have metaprogrammed before in JavaScript. How many of you used object? Object.get keys, object has own property, yes. So all of you have metaprogrammed and the solution, is it metaprogramming for all those problems? I don't know. So what are the ideas behind metaprogramming? So there are a couple of ideas that I want to talk about. Introspection, intercession, reflection and generation. So introspection is when you are introspecting your code. So object dot, what are the properties of my object? Intercession is when you kind of trap the property of an object and we will go see some of these things in ECMAScript 6. Intercession, you trap the property of an object and try to make it behave a little differently. So you have accessor property of an object, you want to make it behave differently, so you intersect it. And then there's reflection, and you reflect on yourself, you reflect on the object, and then there's generation. Generation is like the ultimate metaprogramming. You write code that writes code. So the idea behind metaprogramming is operating on code. So you don't operate on data, you operate on code itself. So ECMAScript 6 gives you a couple of APIs that help you do this kind of metaprogramming. The symbol is, symbol, reflect and proxy are three APIs that we're gonna see today. All right, symbol. Let me quickly change, and so I was actually successful in building spider monkey, but I'm gonna use Mozilla anyway right now. Symbol is a new primitive, right? And symbols are also unique. Why are we talking about symbols, and what is symbol? Symbol, the API symbol gives you a list of well-known properties, like symbol.iterator, symbol.to. So these are the well-known symbols, right? Symbol.hasInstance, symbol.isConcashSpecable, symbol.iterator, symbol.match, and so on and so on. So all of these, when I tag them to an object, you can modify the behavior of an object. Let's take a look at symbol.iterator and go through an example. So I have a list, let's say let xs is equal to one, two, three, four, five, and I'm gonna have to, let's say I wanna loop through the list. So I do let for the x of x is this visible? Yeah. So it's gonna give me one, two, three, four, and five. Now I wanna modify the behavior of this except. So ECMAScript 6 has this iterator property. So for the for loop goes through the iterator event of this xs. By default, it goes through every element in the list. What if I wanna modify the behavior? Then let's say for some random my business use case is that I need to go through only the odd numbers in the list. There might be more complicated business use cases, but I want to go through only the odd numbers in this list. And what I'll do is I'll create a, let's say an iterator or a generator. And I have, so this is an iterator basically, which yields every odd number. So this is the ECMAScript syntax for a generator, function of star, and then you do initially let i is equal to zero and then you yield the first one and then every other element you kind of get it. So what I'm doing there is just creating an iterator. And now, so I haven't yet assigned symbol dot iterator to xs. So I'm gonna just confirm that I haven't. And it says undefined and there's nothing there. So xs does not have any property symbol yet, but now I'm gonna assign a property symbol, assign the symbol dot iterator to xs. So now xs has a symbol property. It has a symbol dot symbol dot iterator and symbols are unique. So now when I do a for let x of xs, it goes through this iterator, this logic and not the default iterator, 1, 3, 5, 7. So what we are doing here is altering the behavior of the language itself for some particular data, for some logic. And these kind of situations might arise in a lot of complex business use cases. You might have a domain specific data set or you might have a domain specific business that might require just some kind of custom logic that you have to use whenever you're looping over some sets. So this is an introspection and an intercession, both combined. So what we're doing is we're first assigning a symbol dot iterator for an object. And then when we are iterating over the object itself, we are intercepting the for loop and then we are putting in our custom logic there. So that's the symbol. So now that we've altered the conscience of a for off loop and there are a couple of more things that you can do with a symbol and let me just walk through them. So ECMAScript 6 also has computed property keys, computed object keys. So what you can do is you can create an object and then you have multiple computations that can create a key basically. And you can do that with symbols as well. So you can have a symbol and then you can compute that and create a property key. So you have on your runtime, you can have complex logics and you can just create keys on the book, compute and create keys on the book. There is a global symbol registry and this is kind of weird. So when you create a symbol, it's created locally and then when you have to create a global symbol registry you have to use the symbol dot for and we've seen that symbol have some well-known methods. So symbol dot for is one of the well-known methods and this is in TC39, the whole specification. Do look it up. So the set of symbol properties. So when you do symbol dot for, it creates the symbol in a global scope and when you see if they're equal, they're not equal. So the local scope is different from the global scope and something that's weird is if you use an iframe and if you don't use an iframe, they clash, the scope is polluted there. So the computed property key here, what I'm using is modifying what a class is. So what I'm doing here is creating a class js4, constructor, this dot participants and I'm intercepting the instance of operator here. So what this does is when I create a new object, new js4 of 10 and new js4 of 1000, I use the instance of operator, this is going to evaluate to false and the second one is going to evaluate to true because I am intercepting the instance of here and I'm saying return true, only if the participants is greater than 500. So js4 has high standards and we want to use this kind of logic to make some objects of a class an instance and some objects not an instance. So those kinds of things are also possible with symbols and there are other well-known symbols like symbol dot is concat spreadable which is going to control if two of your objects can be concatenated or not and unscopable wherein you can control the scope of a particular element of an object, let's say. Within this scope, if you have it might not change and out of the scope it might change and controlling where it can change and where it cannot change. So let's go to the reflect API. So reflect, so that was about symbols and symbols provide you a very strong way of defining custom methods for an object and it has a list of well-known symbols, well-known methods which you can use. So the reflect is a V2 of object basically. It has a lot of, let's look at some reflect. So this is the MDN documentation of reflect. So it's a built-in object that provides some methods. So it has reflect.apply, construct, define property, delete property, enumerate and all of that. So why reflect and why not object itself and a lot of object properties are convoluted, a lot of object properties are sitting unused, a lot of object properties are, some object properties do not apply to functions. So reflect has properties that can apply to functions as well and so you have an object and then we can do reflect.get and then we can do reflect.set and it comes to the whole set of APIs. So why reflect, it's the V2 of object basically and we'll see how reflect will help us further in combining proxy and creating a much more powerful DSL or much more powerful metaprogramming API instance. So coming to proxies, proxies are the most powerful metaprogramming API of ECMAScript 6. So what proxies do is proxies intercept your, proxies intercept many things. Proxies intercept your object property, a function call and behavior of an object itself. Let's go and check out what proxies do. So what I'm doing here is creating an object, let me create a handler. So this handler is where I'm gonna intercept that call. So I'm gonna create a function which is gonna accept a target and a name. So I'll create a new proxy and this is how I create a proxy, this is a direct proxy and the target is, so I wanna create a proxy with my object and then I'm gonna intercept with this handler. Create a proxy with this object and intercept with this handler. So here X is my proxy or we can say P is my proxy here and whenever I do any operation with P dot whatever it's gonna, the handler is gonna intercept that call. So what is happening here is, so I have created a new proxy and this is the object here and I do P dot hello and the handler which has a get property is gonna return, is gonna apply that function here and return me the result there. So that's a proxy and this is quite powerful in some senses. So what we can do is things like we want, let's say we want to check if the name is a particular thing and then return one is two. So things like that is possible and this here is operating directly on the code itself. So we are generating this, we are returning a specific function, we're returning a specific data for this property, P dot bar for the bar property and for the foo property and so on. So every time I'm calling these things there is a new, it's checking the name of the property and then generating a new result. And this kind of introspection and intercession leads to a set of powerful programming techniques. So for those of you who might have heard of Rails, Rails provide you active records and it has these very powerful get all records by get all records by some column name, get all records by some field and value. Let's try to sort of mimic that functionality here. So what we can do is, so we are already able to get the name of the property. Now all we have to do is create a function. Let's say we return a function each time we create that property. So before doing this what I'm intending to do is whenever I call, let's say I have a DB variable and whenever I call a column name of 10, I want to select column name from DB limit 10. That's what I'm gonna do. And if I do column name two, I want to select star from column name two limit by 10. Select column name two from DB limit by 10. If I have to do column name three, DB dot select column name three from DB limit by 10. So that's what I'm gonna do just with the proxy functionality. So what we can do is capture this, intercept this 10 here. So let's say limit, let's see if that works first. Have to create a proxy. Yeah, so it's capturing that. And what we'll do now is quite simple. Now that we have the name and the limit, sorry about that. What we'll do now is now that we have the name and the limit, we're gonna build a sort of a factory for returning SQL statements. So all we have to do is select, not sure if it's capturing the target yet. Yes, it is. So it's quite as simple as that with proxies and we can extend this to any column name and any variable as possible. So the power of this is in its simplicity itself. With a couple of lines we were able to create a decently advanced DSL here. So we have a variable name and we have a key. All we have to do now is whatever, we don't have to define 10, 15 functions. We don't have to give 10, 15 select statements. All we have to do is DB dot your column name and then the limit and so on. And this is quite extensible in many fronts and the power of proxies can only go more and more deeper from here. What you can also do is define a lot of custom operations. You can actually implement JavaScript object functionality within JavaScript itself now. It's almost bringing homo-iconicity to JavaScript proxies. Let's do something else that's quite powerful with proxies, one more example then we can. So what we're doing here is trying to bring in a Python's kind of negative list slicing to JavaScript, right? That's one of the features I love about Python. So let's try to do bring it. So right now if you want negative slicing all you have to do is array dot slice minus and it's not kind of, it doesn't look good and I want to do it with the braces operator itself. I want to do that with the accessor property. So that is quite possible with proxy too. So I am going to create an array. I'm going to create an array and capture the get again and what I'll do is if the index is less than zero I'll do some logic here, target dot length and index and then use the reflect API to get that particular property. So if the index is less than zero I am computing my property key and then returning that property key with the reflect API and then I'll wrap the proxy again around the array as usual and try to intercept this behavior of the array. So yeah, already coded it. Sorry about that. I didn't want to take chances. So that's how it works. So you can, so array of minus two is be here and what we did is kind of create a custom object type in JavaScript. We created our own object type. So you can extend this to get, you can extend this to set you can extend this to all sorts of features and functionalities that's possible. So the symbol reflect and the proxy when combined together offer a set of interesting and kind of exciting functionalities. So this is in no way the limitation of proxy and there's a lot of cool things possible. So ECMAScript itself nobody is done yet. So the spider monkey is currently one of the most implemented a lot of features are implemented. This is cool link here which is the conformity of all ECMAScript features within different engines. Babel.js is sufficiently advanced. Babel.js is what you use for transpiling ES6 normal ES5 JavaScript and Chrome is kind of lagging behind in ECMAScript 6 implementation for some reason and it seems to be doing well too. So the idea of this talk was to provide sort of a insight into what are the possibilities within ECMAScript 6 and the point with JavaScript and ECMAScript 6 is that it's more iconic and a lot of metaprogramming principles and a lot of metaprogramming aspects is lost when it's when a language is not more iconic. The concept of code and the concept of data being represented in the same language is not present in JavaScript. So there's a the way it works. So compilers are basically big metaprograms. So compilers take one language and then compile it to another language basically. And the way it works with ECMAScript 6 is the language JavaScript is translated to an abstract syntax tree which is not in JavaScript itself but it's some kind of a representation. So that homo-iconicity is being lost and we have a powerful set of new features now which is the reflect, the proxy and the symbol that we can use to kind of intercept objects, intercept properties and then create custom definitions around it. Why are these useful and why are these powerful? A lot of time when doing normal programming we tend to repeat ourselves, right? Function names multiple times, right? A lot of repeat a lot of redundant code and kind of customizability that metaprogramming brings is powerful in the sense that it reduces code and it reduces complexity to a certain extent. But metaprogramming is also a bane in itself that some people rather me itself find it confusing sometimes and the whole point of write code so that you can debug it tomorrow, write code so that somebody else can read it is sort of being lost with metaprogramming to some extent. So use metaprogramming and use metaprogramming sparingly whenever you're comfortable with it and whenever there is a somebody favorited my tweet, thank you, whenever there's a need for it, right? So it is a journey and there is no one correct path. There are a lot of ways the world is evolving today. A lot of ways there's complexity being introduced into the system and metaprogramming can as pure but it can, was it okay till now? Wow, feels a lot better. Metaprogramming can feel, this is too loud, can feel better sometimes and it can lead to many complexities too and software engineering has always been a problem and it'll always be a problem and it's up to us and up to our thinking and conformity to standards that we can improve our ecosystem. I think that's about it, thank you.