Does hearing about potential new features of Javascript makes you excited? Then this talk is for you! We will walk through a few interesting proposals from TC39 from stage-0 to stage-3. Let us see how beneficial these proposals are with code samples and some live coding.
ES?.next()
From:

JSNation Live 2021
Transcription
Hello JS Nation. We are talking about ES Next in this talk. I'm Hemant. I'm a member of technical staff at PayPal, a GDE in web and payment domain and of course a TC39 delegate and you can tweet to me at Gnumenth. ECMA, the European Computer Manufacturing Association International has many technical committees that decide and define the specifications of different entities and one such, the 39th is the TC39 which works on ECMAScript. How does the process basically work like? So we have basically five stages starting from stage 0 to stage 4. The first stage is called a straw person. At this stage you allow input into the specification. It's more like you have an idea and it's not yet presented in the committee and stage 1 is more like a proposal. So you have an idea and you make a case for the additional and then describe the shape and of the solution and what you're trying to solve and what is the solution like and what's the problem that you want to solve for is what you discuss here at stage 1. And at stage 2 you have a draft where you precisely describe the syntax and semantics using formal specification language and then at stage 3 you have a candidate which indicates a kind of hey this can be tested with a flag maybe on your browser or a node environment so it's kind of you're seeking feedback on candidate from developers and saying hey use it with caution because now it's under a flag just use it and let us know how it looks like. And finally at stage 4 it's finished and it's ready to be shipped and sometimes it's already shipped with the flag as I said in stage 3 the flag is kind of removed at this stage and it's available in most of the modern browsers and other environments. That's the whole process of how TC39 works like starting from straw person to the finished after the proposal draft and candidate of course. Interestingly this was called as straw man before and it's renamed to be straw person which makes a lot of sense. Here's an interesting graph which is being pulled in the current stat where we have proposals from stage 0 to stage 4 and we have 18 such proposals on stage 0 and 79 proposals on stage 1. We have 26 on stage 2. We have 14 on stage 3 and 49 on stage 4. So during this talk we would be going through some interesting proposals in each of these stages. And word of caution of course because we are talking about some of the proposals which are at the very early state of course they will change some of them might even change how they behave the syntax might change some of them might not even make it to the final state. So don't presume that all of these features will be available in JavaScript someday. So these are some of the potential future features that we will be looking into. So I kind of mark each of these slides with these two emojis here on the left what we see here with the classic icon is more like with an IP saying that hey this is how we are doing it today and on the right with the glasses is what we are saying hey how the future would probably look like. Let's say I have an item lib and you have a function get players which kind of gives you an object which has characters and has attributes on strength and you need to pull some information out of it. So the item lib is giving you map take while and for each methods and the get player here with the val gives you an object. So you want to map over it as of today you do a map.call on the value and fetch all the characters and then you do a take while and say hey if the strength is greater than 100 give me all of those and finally you would probably have to for each and do some processing in this case we're just console logging the value. Can this be better? So on stage 0 we have this binding syntax which makes life easier with the bind operator if you can think of it as two successive colons here what we see after get player you have map and then you have take while and then you have for each. Isn't it simpler compared to how we are doing it today probably and how precise and simple it looks like here at stage 0 we have this bind syntax. So this bind syntax if you were to summarize in the different variants that it provides if you say object with the bind operator and function which is equal to function.bind of object followed by the bind operator object.function which is indeed equivalent to object.function.bind with object. If you have object.bind with function value that's equivalent of function.call object,value and if you just have bind object.function value which is equivalent to object.function.call object,value. This makes lives much simpler and intuitive to read understand and also the syntax looks beautiful isn't it. Let's see another example here. You would have probably done this multiple times if you have an object and you say you have an object with a lot of attributes in it and you're returning particular attributes or you're trying to have a different name for the attributes. So in this case say you have performance as one of the attribute perf on ops so you would probably say perf is perf.ops or if you have object of X you would say X is object of X and with the bracket notation or if you're destructuring you would probably do it like this. So wouldn't it be easier if we have an easier way to do it rather than saying perf is op.perf rather I would just say op.perf which should mean that perf is op.perf right and say you have coordinates as O of X with bracket notation as we saw in the previous slide it should mean that X is O of X right. Same thing with destructuring you could you could just say O of X that is as good as saying X colon A of X and object notation of X as A of X. So this is a shorthand property assignments on state 0 which makes life easier. Let's see another example where we have make adder a generic function which takes an argument X and which returns a function which again accepts an argument Y and finally it returns X plus Y. So you could do a make adder of 1 and get add 1 and then you could say add 1 and passing 2 to it you would get 3 passing 3 to it you would get 4 so basically it's an make adder of 1 which adds 1 to whatever input it's being presented with. Similarly we have add 10 and this is called as partial application because we are partially passing the parameters that is required for this function and interestingly on stage 1 we have partial application as a proposal where if you have a function say sum which takes X and Y and returns X plus Y you could say add 3 comma question mark. You're partially applying from left and saying hey I would produce this parameter later on and pass it on to add 1 whenever I need and this should be probably called as add 3 here because we are passing in 3 and we pass in 3 to it and it adds 3 to it and you get a 6 and you could also do an application on the right saying add 5 and you add 5 to it it becomes 7. Similarly you can do a partial applications from left right for any argument in the function argument so you can have multiple question marks and you could pass in those arguments whenever you need them to and you could also do an invocation with O.F or you could just have a function it could be an method on the object so it it could also be in a partial application that's allowed on the super property. So you get the magic here so you could do a left right or any kind of partial application which would definitely help if you're from the functional paradigm or where you're you know solving your challenges in a functional way which is definitely an interesting proposal to look out for. The other interesting proposal on stage 1 what we have is pattern matching which kind of gives you this method of match and gives you the functionality to say hey match take this input and then say when this input is of a particular pattern I want this behavior. Here's a classic example where you're you know fetching from a JSON service and you get a response and you could say when my response status is 200 and my header has a content length and fetch the content length as S you could extract that S out and you know you're logging your size here the header size. Also you could operate on the response and say hey if my response status is 404 then go ahead and say JSON not found and you could also go and destructure the status and say hey if my status is greater than or equal to 400 then throw a request error. So this makes life much easier than having a nested if else or a switch and condition where as of today you don't have a straightforward way to do this kind of pattern matching JavaScript and this makes it very interesting to you know apply pattern matching to your problems and try to solve it in a more precise and the compact way. It's an other extension the announcement that recently got added into this proposal on stage one is having an async match you can have an async match with an await matchable and and do the same thing how we will do it with a non-async way of matching you could say when a you can await and when B you could do B.then so basically it produces a promise and you could do an async match with pattern matching as well. The other interesting feature what we have on stage one is do expression so the do expression basically helps you to you know have a block within do where the last statement is written by default say you have in this example X where you say temp is a function call and you say temp is temp into temp plus one that's what the default value is written but how is it really useful say if you have multiple branching in your code and how do you do it today suppose you have constant let or a combination of that in your code or you want to wrap it within a function to you know to maintain the scope and things like that here's an example of multiple branching you could do it as easily as saying hey here's my do expression and I have my if condition if if foo is matching then I would invoke the function F and that's written value would be assigned to X here else if if it's bar then you would go ahead and invoke G and that the value of the invocation of G would be assigned to X here again or else you would call H so you could you could see how intuitive it looks like compared to probably you would have done this with a ternary operator and have nested conditions within which kind of makes it makes a code bit ugly and probably even debugging tougher times here's another easier you know syntax for JSX this probably most of our friends who are into react would have faced say if you want to conditionally render components you would probably put a ternary operator on it or probably use another component which conditionally evaluates the logic required and renders the required component right so it kind of gets a messier here's a view here's how beautiful it looks with do expression you say you have a nav you have for the home component and you say do if logged in show the log dot button else showing the login button component so it's so easy to you know express that here with the do expression of course do expression doesn't just stop there let's see another interesting proposal see as of today if you're using promise dot all with which has a weight within it you would probably wrap it with a sink functions immediately invoked a sing a sing functions because you can't really use a weight in the top level unless until you are in MGS right so until unless you are in a module basically so if you use it today you do promise dot all and wrap each of them with a sing functions and then you would go ahead and fetch the results and operate on it so I think do on stage one is exactly this proposal which is more like an extension of the do expression but on the async level which makes things even more easier instead of wrapping them with an immediately invoke a sing function expression you could just say I think do and then passing your statements of fetching or any of it or the the logic required for that async block so you can do an async do and this makes you know the code much more readable and you don't want to crack your head and wrapping it again with an you know immediately invoke a sing function so this is on stage one as into expression and operating overloading on stage one there's this big debate that does JavaScript really need operating overloading does it really help and this proposal is trying to explore that and here's an example with decimals which says with operator decimals which where it's trying to overload the meaning of plus equals and other operators and and try to get a meaningful expressive syntax and behavior with operating overloading and the whole intent here is to have such libraries where if the operator is overloaded it helps you to make better and easier expressions which kind of help helps you to basically define methods that is particularly useful for your domain in this example we have decimals which are of overloaded with plus so if you say decimal 1 plus decimal 2 you get a decimal 3 and similarly here's another example from the spec which says with operators from CSS numerical values you could do a query selector on style and pad left with CSS m3 or CSS px2 and this is how probably you would go ahead and overwrite those operators you would say you lose the operator function here and say hey my plus is defined in this way and my multiplication is defined in this way my equality is this and my left and right how do you evaluate so you get you get the idea on how you could overwrite the operators and and finally you would you extend the decimal operator for the class decimal and then the new big would probably would get the definitions of the overrided overloaded operators basically for what what's been defined here for the decimal operators and stage one we have string.ddent luckily I'm one of the co-champions for this proposal if you have used template literals to generate code basically you would have faced this problem on how difficult it is to indent within a template literal so the indentation is maintained and once your code is generated so the same indentation is maintained across. Here's how the string.ddent would look like you would have the ddent static method on string we've said string.ddent which also supports expression so you have an expression here which gets evaluated and that would be replaced in the output with expression and if you have spaces the spaces will be maintained it will not just like get trimmed off so you have this supports expression as you expect and expressions with white spaces will not be removed right so this this makes life easier when you're trying to gen you're trying to write code which generates code or you're trying to spit out something on the console which is formatted in the right way and or if you're writing on SQL statement or SQL query which you want to execute as well as show it in the output and there are many such use cases but string.ddent on stage one is a proposal that makes things easier in this realm. The other interesting proposal what we have is the the pipeline operator currently it's an unsettled syntax there are like four variants on how pipeline operator can work and here's an example I've picked up one of such syntax say you have two methods double and increment which obviously does doubling and increments by one or n whatever you pass pass you taken n and add one to it without pipeline operator you would probably would have to have this nested calls you would say double increment double and double that's the use case so if I give you five you should get 42 out of it so with pipeline operator the basically what it does it needs an expression and then it has the pipeline operator there and it has a function so if you were to say five double and double and then increment and double you would get 42 and that's how beautiful the syntax looks like so this is on stage one the pipeline operator and object on has on is on has on is on stage two this is one of the interesting proposal that directly landed to stage two when presented to the committee and all it does is it gives you this beautiful shortened method if I could call it saying that object or has on which takes the object and takes the property and says whether the property is there or not as of today we'll probably have to do object or prototype or has on property and call the object with that property and then check if it's there or not so instead of going through that kind of a long chain function you can just say object or has on passing the object with the property it says whether the properties are has on it as does that property has this property has its as its own property or not so that's object or has on on stage two and we have map dot prototype dot emplace this this this is a very useful method if you're if you're working on maps today say if you were to check if a key is present in map or not and then set it and then get the value you would probably do map dot has if map doesn't have that key then go ahead and set it and later on you can get and do things on it with emplace it gets very very cheeky and easy you could just say map dot emplace key and then insert the value and do the thing so map dot emplace basically takes a key and gives you update and insert values so you need not crack your head on checking whether your map has it you already if it is there then updated if it's not there then created so all of this is taken care by emplace so so map dot product dot emplace on stage two and on stage two we also have record and tuples so you could think of records as deeply immutable object like structures here's an example of a proposal which has ID title content and keywords and then you go ahead and say proposal dot title it prints records and tuple and then you go and spread it like objects and say title is stage 2 record and tuples but if you go and say proposal to dot title it says stage 2 a record and tuple but your proposal would still have the same record and tuple so it's more like an immutable object like structure that's that's record for you and tuples are mostly deeply immutable array like structures similar to records you can say hash followed by 1 2 3 that would be a tuple and then you could say with 0 comma 2 to kind of get those parts of the tuple in this case it's it's a cake go ahead and replace the 0th index with 2 so basically you get tuple 2 to be equal to 2 2 3 whereas tuple 1 is 1 2 3 and these two aren't equal so you could also do spread of those you could you could say pushed with 4 you could use the popped method so so all of these methods are available on tuple which basically helps you to have an array like structure but it's deeply immutable so if you're into immutability and functional programming probably would be using immutable JS and likes and records and tuples gives you that strong ability of having immutable structures in your program and fine last and fine last index is another proposal on stage to say you have an array of values and today if you were to try to find the index the last index or the find of the last element in the array you would you would probably try to take the array reverse it out and do a find index right here's an example where it should have been minus 1 but it is 4 you're taking an array reversing it you're doing a find index and saying value is equal to equal to 42 it should have been minus 1 but it will be 4 today if you see your array has values of 1 2 3 and 4 with find last method on array you could just say array.findlast and give it the condition here we are saying if it is divisible by 2 then give me the last one that's divisible by 2 you would get that value and you could also do a find last index if it's if you're working on the index you could get the same idea here where you say n.value is 41 give me the index here it gives you minus 2 because there is no 42 here all of the values are 1 2 3 4 and divisible by 2 give me the last index that's divisible by 2 you get 0 1 2 and you get that as the result on the find last and find last index and basically you have the throw expression on stage 2 which is also an interesting proposal say if your if your function is receiving a parameter and it expects it to be there you could throw a new type error inline rather than asserting it inside the function to check whether the parameters are available or not you could also do it within the arrow function bodies or you could do it with conditional expressions and and basically also in logical operators so you could throw this new error wherever it's required inline which is useful and if you're from programming languages like Perl where you could say or die a similar thing you could do it as an expression you can throw the throw an expression wherever you want and on stage 3 we have art on built-in indexables say you have numbers of as as arrays or you have name a string or have your unit 8 array you could use the add method to fetch or whatever element you want at that particular index so if you say nums of and nums at 0 you could get 0th and nums of minus 1 you get 3 that's like going from the last index those minus the negative indices suggest that hey go and pick the last element from that so if you do minus 1 you get 3 you do minus 2 you get 2 and if you say 100 or something you just get undefined which is not there in that range and you could do the similar things for strings and unit 8 array and error cause is another proposal where I'm co-championing this is an interesting proposal which kind of adds you adds an option back to the the error constructor if you if you were to throw a new error you could pass in the cause and say hey this error was caused by this particular failure or thing right so you can say you have a function and then you're throwing a new error as of today you would say hey this failed because of this error but what is the exact cause and how could you see that in these track trace right so that's where error cause in place in key role so you have an async function you're trying to fetch some data you catch the error and you console log the error and then you console log the error caused by E.cause and that cause is the cost that was thrown here in the fetch data so the output you see is error unable to fetch data HTTP as example.com caused by type error failed to fetch so that's the cause that's the error that gets passed in the the cause attributes in the option that's passed to the error constructor so that's error cause on stage 3 and on stage 3 we have a top level await if you were to say do await.promise resolve or any promise function as of today I would say await is not a valid function because it needs to be wrapped in an async function but within modules you have top level await where you can have await at the top level so if you were following this for some time now you would have seen that there was an article written about how top level awaits are a foot gun but then the same author went ahead and saw the proposal of how top level await is useful and then said yeah it makes sense within modules and today we have it on stage 3 and soon to be on stage 4 and that's all we have for all of these immense and intense and exciting proposals and hope you like them. Thank you. Thank you Hemant for this great talk. Now let's jump to the polls. What type of proposals do you like the most? I hope you all answer and the winner is syntax sugar with 32% followed by fresh paralyzed with 30% new operator by 20% a new method on the prototype by 16%. Do you find this interesting Hemant or do you find this surprising or what are your thoughts about this? Yeah it's pretty interesting and also it happened to be the very first options in the questions and people normally like syntax sugars because it kind of makes programming constexp easier and you know looks the code looks more precise and concise and and that's why I feel the maximum vote has gone to syntax sugar and we are still seeing it's going up. Okay nice. Now let's jump into the questions. Bartos is asking apart from the negative indices what is the use for the case of add function? Yeah it's not not only just negative indices you can also you know say add any index you want and if you look into the DOM APIs as I mentioned in the talk it also has the similar approach of getting the index from the model list so it helps you to get an element that appropriate index easily and negative index is also an add-on to it where you could go and fetch the element in say at the last pick it up so that's the advantage. Okay thank you. Giambo asked it is possible to vote for those proposals or is a job for the RF committee? Well yeah we don't apart from the committee people don't really get to vote for the proposals but there are too many forums where you can discuss about proposals and share your ideas and thoughts and there are also at times a tweet which turned into a proposal and got implemented so it happens all in the open but the meetings happen in closed environments but the notes are always open folks can read the notes and we can provide feedbacks on the proposal but not really voting because voting happens in a room where we have implementers who get the who have the authority to say hey this might cause a memory leak or this is pretty complex to implement in a browser who have who have more idea on how the implementation should be done and apart from that all the members of the committee get the rights to vote for the proposals. Okay thank you. The next question is does the committee consider TypeScript compatible when vetting proposals? Well not really so this the ECMAScript is more like a specification that languages implement and JavaScript happens to implement that and it's complaint for ECMAScript so the whole motive here is to not not to break web and it's definitely influenced by many languages when the proposal comes in but it doesn't really as as the process it doesn't really look into hey is it compatible with TS or is it compatible with any other particular you know construct or language. So it doesn't even really talk about how the implementations will happen to it. It goes one level higher and talks about the specification and likes. The next question is from from me like how is to be in the committee? Is this fun? Is this difficult? How is interacting with the other people like the proposals, the votes, how is in general how do you like it? It's amazing like being surrounded with a bunch of very smart people and at times we have Brenda and I, the man himself in the room and it's really humbling and you know the people are so super smart and they kind of bring in edge cases to scenarios. I remember one of the conversations we were having about dates one of the gentlemen brought up a particular date format we had never heard where you know the months varies and you know the days varies kind of thing so they can also like just quote the ISO specifications and without even looking and referring and so like amazing bunch of folks and there's so much to learn highly influenced by all of the smart people in the room. That sounds super amazing so we invite more people to see these proposals to comment and yeah thank you very much for this great talk and I want to invite Matthew on stage.