📜 ⬆️ ⬇️

The Better Parts: Douglas Crockford talk on JavaScript and future programming languages ​​from .concat () 2015 conference

Who knows more about JS than one of his "fathers"? On HolyJS 2017 Piter will come the legendary Douglas Crockford, the creator of JSON and the author of a variety of JavaScript tools. On the eve of his speeches in St. Petersburg, we publish a translation of his speeches in .concat () 2015: The Better Parts - about how to use existing programming languages ​​more efficiently and what will be the programming language of the future. Although more than a year has passed since the speech, the report touched upon a number of “eternal” questions of programming, which we are sure will be relevant in 3-5 years.



The path to perfection


This man - the famous aviator and writer Antoine de Saint-Exupery. Most remember him for the fact that he is the author of the wonderful children's book “The Little Prince” (although this book is not quite a child’s book). In addition to her, he wrote many other books, and in one of them there is an amazing phrase: "As you can see, perfection is achieved not when there is nothing to add, but when nothing can be taken away."

This is a brilliant quote. It was used in conversations about design, architecture, attracted to everything that combines creativity and discipline.
')
He talked about the design of aircraft. But it seems that the idea is actually wider. I think that it is best suited to the computer program. Because we have a special relationship with perfection that is missing from other disciplines: what we write must be perfect, or it will behave incorrectly. And the author gives us some insight into how we achieve perfection through subtraction.

I think this also applies to programming languages.

Programming languages ​​tend to be progressively more complex. But if we want to achieve perfection, it is necessary to remove some things from there. This is the principle of strengths. According to this principle, if a function is useful in some cases, and dangerous in others, there is a better option, always use the best option.

This is a surprisingly contradictory statement. There are many people who do not want to use the best option. And this happens because of a misunderstanding of one thing: we are not paid for using each function of the language. At the end of the project, there is no portfolio manager checking: “Did you use double equality?” No one cares about that. We are paid to write programs that work well and are error free.

When did “no mistakes” become part of the deal? It has always been part of it. We just rarely achieve this. It is easy to forget that in fact the absence of errors was the first requirement. Therefore, a good programming language should teach you this.

I encourage people to learn as many programming languages ​​as possible, because each of them will give you new ideas that you can apply to other languages.

The language that taught me the most is JavaScript. I had a lot of time to deal with it, because I made every mistake that could be made in JavaScript. And I started from the very first - the worst - I did not bother to learn a language before I began to write in it.

In the end I learned the language, and he taught me. And he continues to teach me. I used this language to write a tool called JSLint, which reads JavaScript programs and tells you how to make them better. And JSLint taught me even more. All this has changed my point of view on programming, so now my main goal is to try to create programs that do not contain errors. And JSLint gave me a lot of information on how to do this.

I wrote a book about my experience using JavaScript and JSLint code - “JavaScript - Strengths”. You may have heard of her. It is still the best seller, which is rare for software books. Most software books become obsolete even before they are released, but this one is still relevant. That's because the "strengths" are still strengths. Well, the language has not changed at all.

Counter Arguments


Now the arguments against the use of "strengths". I would like to present them for you:


So, the purpose of programming languages ​​is to help developers create programs that do not contain errors.

We used to think that writing good JavaScript programs was simply impossible, because it was such a fragile language. But it turns out that writing good JavaScript programs is not only impossible, but not necessary. Just because of its fragility, JavaScript requires more discipline than any other programming language. And you really have to stick to it in order to write something that will work.

There are two things that work against it. First, it is a fantasy of infallibility. In particular, young programmers believe that their skills are so advanced that they can do amazing things that will work. Secondly, there is the futility of impeccability, which you see especially with old guys who have been doing things that have never worked for years. These two very different views lead to one and the same: danger driven development. And that's bad.

One of the things that complicates the management of software development is the complexity of planning. There are two times you should be aware of. Time A is the time it takes to write code. We really do not appreciate it - we do not have a science that would answer the question of how to estimate time A. But the situation is even worse with the estimation of time B - the time required to make the code work correctly.

Time B should be 0, right? You write code - it should work. But time B sometimes becomes more time A. Sometimes it is infinite. This happens when you have a software project that ends, but then it is abandoned before it starts working.

Everything you do within time A, which increases time B, is wrong. You should try to reduce time B to zero.

New strengths of ES6


There are a number of additions to JavaScript that will be sent to the ECMA General Assembly in June of this year ( these innovations really went through a certification procedure and became part of the new specification - ECMAScript 2015 Language Specification, - ed. ).

I am glad to announce that there are some new strengths. And today I would like to share them with you.

Tail recursion


The first and the best is a construction called tail recursion. If the last thing the function does is return the result of a function call (which may be a call to another function), instead of creating a reverse call sequence, the compiler generates a jump. So the code will work a little faster, which is nice. But even better, for some models it will significantly reduce memory consumption. Thus, a completely new class of algorithms can be used.

For example, we can use the continuation transfer style and other types of programming that we could not implement in the old language. So with this function, JavaScript finally becomes a real functional programming language, and that's great.

Dots


We also get the dot operator. If we put it in a list of parameters or arguments, we can deal with a variable number of arguments, which is really nice.

Here we have two versions of the curry function. The first is in accordance with ES6:

function curry(func, ...first) { return function (...second) { return func(...first, ...second); }; } 

The second is how it was implemented earlier:

 function curry(func) { var slice = Array.prototype.slice, args = slice.call(arguments, 1); return function () { return func.apply(null, args.concat(slice.call(arguments, 0))); }; } 

I will not explain what exactly is happening in the second version, because everything is just awful. The first one, on the contrary, looks quite reasonable: everywhere we see points (here you can have as many arguments as you like). And that's great.

Innovation does not allow us to do what we could not do before. But when you have to deal with a variable number of arguments, this approach is much more pleasant.

Modules


Now we have modules. You can import and export values ​​from different files; and it finally has support in the language. Previously, all this was implemented through global variables, and it was terrible.

Now we can do it right. If you don’t feel like it’s great, try implementing the same thing in accordance with the previous standard. But with ES6, we can finally do it right in a fully asynchronous language, without blocking.

Constants


We have two new ways to define variables: let and const, which solves the problem of block scope. It turns out that in a good program you do not need the scope of the block. But JavaScript syntax previously looked as if the block had a scope (with its var syntactic construct), although it was not so confusing to people. Every time due to confusion there were errors. Let and Const allow this to be avoided.

Again, new designs do not allow writing any programs that we could not write before. But now the code does not confuse Java programmers, which is good.

Destructuring


We have a destructuring, which is another syntactic candy. It also does not allow you to do what you could not do before. But for some things, the new syntax is much more expressive.

For example, here I have an object. And I want to create some variables by initializing these variables from the properties of the object.

 let {that, other} = some_object; let that = some_object.that, other = some_object.other; 

This is a very simplified example. Later I will show you another example of how you could use this.

Weakmaps


We had a WeakMap. WeakMap works the way objects should work. In JavaScript objects, keys are strings, which is an error. It would be better if some values ​​were used instead. But, nevertheless, these are strings. WeakMap solves this problem. Here you can take any value and use it as a key.

Unfortunately, we had to add this thing, and it greatly complicated the language. In addition, we called it the worst name ever used in programming languages ​​( weak - weak, Eng. ). No one wants to put something weak in their program. But this design works really well.

With WeakMap, you can write programs that could not be created in the language previously.

Pattern lines


And finally, we are something that I called the megastroc literal (in the language this is called patterned strings, but I don’t like this name; but previously they were called quasi-literals, which was even more confusing).

These are regular expressions that correspond to multiple lines in ES6. Announcement of this regular expression is just awful; I hope someday we will do something better. But in ES6 we have no better alternative.

So, we have a function that takes a string and converts it into a regular expression, after removing all spaces. Having such a function, I can take any expression, but not write everything in a heap, but put in it the necessary empty space to see the elements and how they relate to each other. The result will be the same.

This construction has one drawback - the compiler treats the regular expression as a string, so it cannot perform the check. Validation will not occur until we call the constructor. But in the previous version of the record due to the fact that everything was mixed in a heap, serious errors could also easily slip past the compiler. Therefore, I do not think that we will lose much in this transformation.

By the way, if you often work with regular expressions, I highly recommend a tool called RegulEx. Put a regular expression in it, and it will build its diagram so that you can see exactly what is going on inside. I use it every time I write regular expressions.

Arrow functions


Another new feature we got from ES6 is anonymous switch functions. A good motivation for their appearance was that some people complained about the large amount of text when typing the names of functions. So I added such a thing. This is essentially a shorter designation for a function. As a result, I get a function that will take an argument and return an object whose specified property has this value.

Everything is good, except that it does not work properly. If you call this function, it returns undefined instead of a value, because there is an error here. So this is another of those marginal things that are sometimes good and sometimes not. It would be great if it worked all the time, but it’s not.

Disadvantages of ES6


In addition to strengths, ES6 has frankly bad elements.

Classes


The worst innovation is the classes. The class was the most requested new feature, with most requests coming from Java programmers who now have to write in JavaScript and they are really outraged by this. I want to write in Java, but the tasks and money are in JavaScript, so they have to do it. They do not want to relearn, so the new syntax will simplify their lives.

All anything, but relying on this new syntax, they will never understand how the language works. And they will never understand how to use this language effectively, although they will think that they understand. They will continue to write, not knowing how unhappy they are. It is a trap.

Object.Create


I am revising what was written in Strengths, taking into account new knowledge and the need to reflect the innovations of ES6. When I wrote “strengths”, I recommended using object.create instead of classes.

In fact, I was the one who managed to add object.create to the language so that I could use it. It turned out well. But how surprised I was when I noticed that I had stopped using object.create. I added it there for myself, but even I do not use it. And the reason is that I stopped using this.

This


I stopped using this due to the fact that in 2007 I made a project called ADSafe. At that time there were several research groups, such as fbjs on Facebook, Caja Google, Web Sandbox on Microsoft, besides, there was my own project - ADSafe and others. We all tried to figure out how to make JavaScript a safe language, so that we could add third-party code to the application and be sure that it would not cause any security problems. And in JavaScript it turned out to be a very difficult task.

One of the things that makes it difficult is this. If you have this in a method, it is bound to the list of object events (this is good and necessary). But if you call the same method as a function, this is bound to a global object, which completely violates our security. How to handle it?

Most projects dealt with this problem with a compiler that translates JavaScript into JavaScript with many runtime checks and interactions to prevent security issues.

My approach at ADSafe was much simpler. I just made it illegal, prompting you to abandon the programs where it is used. It works. The only problem is that you have to give up the lion's share of the programs, because everyone used this.

However, my hypothesis was that if you remove this from the language, we still remain with a functional programming language, which is enough to write good programs. To test it, I started writing also (without this) in JavaScript, free from restrictions. And I was very surprised to find that I began to write better programs with less effort, without having this. Very cute. Needless to say, if the presence of this in a language in itself causes difficulties: speaking in English, I cannot know in advance whether the construction of a language or a pronoun is meant. It is quite difficult.

Null / undefined


I stopped using null. JavaScript has two minimum values ​​— null and undefined. In some languages, it is believed that you and one should not be. JavaScript is the only language that has more than one such value. But it is absolutely clear that it is silly to have two at once.

Some frameworks attempt to treat them interchangeably, but they are not. Depending on the situation, I have to use only one of them. I used undefined because it is the language itself that uses it: you get undefined if, for example, you refer to a missing property.

Indefinite meaning gives rise to a whole range of problems: a completely wrong type of missing object. We had hoped that this would be fixed in ES6, but this did not happen. Probably, it will always be so. But if you do not use null, then you will not encounter this problem. And I stopped using erroneous values, deciding that their very existence in JavaScript was a bad idea.

Initially, this idea came from C, which uses 0 to represent no, false, and other similar values. JavaScript tried to do the same. But it is confusing.

For


I stopped using for. In ES5, we introduced a new set of methods for working with arrays - for each, map and others, so now I use these tools. If I have an array and I need to process it, I use one of these methods. And I can combine them together in a convenient way. It is really expressive.

For each


I do not use for each. In ES5, we got object .keys (object). This construct gives you a nice array of strings. And it does not include things from the prototype chain, so you don’t need to filter the results. It's nice that I can take an array and execute for each in this way, this is a really expressive way.

I mentioned earlier that the correct tail recursion appeared in ES6. And now it's time to stop using cycles at all (in particular, the while operator) - it's time to use only recursive functions.

For example, this is a recursive function. You call this function until it returns undefined. The first version of the code is written using a while loop.

 function repeat(func) { while (func() !== undefined) { } } 

The second version is written using tail recursion.

 function repeat(func) { if (func() !== undefined) { return repeat(func); } } 

In ES6, these two methods should work at the same speed, consuming exactly the same amount of memory. Thus, cycles have no advantage over recursion. It's great.

Next generation language


I thought a lot about the next generation programming language. What will it be? It should probably be a language with which we will replace JavaScript, because it would be very sad if it turned out that JavaScript is the last programming language. It was unbearable. We should make the world a better place, at least for our children, right?

I was thinking about how this language will be. What properties should it have? What problems will it solve? How do we recognize it when it does appear?

In one thing I am sure: when it finally appears, we will reject it. And the reason for this is that programmers are emotional and irrational abnormal people.

We believe that this is not the case. We think that we are ultra-rational because we play the role of ambassadors of people in the world of computers, and computers are completely rational. Accordingly, we assume that they themselves are also rational. Many of us have lost social skills, but it turns out that the irrationality and emotionality has not gone away. Let's look at the evidence in support of this thesis:


The reason why everything happens for so long is that we cannot change the mind. We have to wait for the generation to retire or die before we can get a critical mass of users of a new good idea and continue to work with it.

I remember when go to came. The argument around him did not subside for years, and then suddenly it became quiet. Can we get rid of him now? Yes, we already just threw it. Does anyone suffer from a lack of go to? All disputes turned out to be meaningless, there was a paradigm shift.

It is really difficult for people to move this paradigm. The history with go to is just getting rid of one construction and changing the way a program is structured. It turned out that the lack of go to facilitates programming.

That is why I believe that the next programming language will be rejected first.

About the classification of languages


Think about how we classify programming languages. I divide languages ​​into two main types: system and application.

System languages ​​are used to write memory allocators, system cores, device drivers — these are very low-level languages. Everything else must be written in application languages.

Perhaps the biggest problem with Java is that its creators could not decide on which side of this division they wanted to be. And so Java is trying to ride both tasks.

We need new languages ​​in both categories. For example, the dominant system language today is C, which appeared in the sixties. But my work is focused on applied languages ​​- most of us will deal with them.

Applied languages ​​can also be divided into two groups: the classical school (which includes almost all languages) and the group of languages ​​for prototype programming, which includes JavaScript.

And I think JavaScript chose the right direction. Causing a lot of criticism, JavaScript contains innovation.

When you program in the language of classical school, designing a system, you need to make a classification of objects. It is necessary to analyze all the objects in your system in order to understand what they consist of, to conduct a taxonomy, to find out how the classes will be connected with each other, how and what will be implemented. All this is quite difficult, since it is most often done at the beginning of the project, i.e. at the point where you have a minimal understanding of how the system should work. Therefore, invariably you get the wrong taxonomy. And so you end up with incorrectly selected objects. And from now on, you fight them. All this does not allow to solve the problem correctly. You want to have multiple inheritance, but all this simply does not work. , , , , , , . . , , , . , ( ).

- . . - , . JavaScript, ( ), . .

Java-. , . — , , .

. . , , .. . , , 1995 . But not today. . . , — . - .

, , . , . , . , . , . , .

. JavaScript , . , . , .

, , - . , — JavaScript .

, . . , . .

 { let a; { let b; ... a … ... b … } ... a ... } 

JavaScript , — , . .

 function green() { let a; function yellow() { let b; ... a … ... b … } ... a ... } 

, , , ( — ).

, , ? . , . , A?

, , . — , heap, . .

, , ES6. , constructor:

 function constructor(spec) { let {member} = spec, {other} = other_constructor(spec), method = function () { // member, other, method }; return Object.freeze({ method, other }); } 

. , .

, , , . - , . , . , , . — , .

. , .

. , . . , , - , . .

return. ES6 : method. , , .

. , , . JavaScript. , . - , Pascal, , , , . . . , , , . . , .



, . 2001 Java JSON. this. index, int. , , . , .

, 2001 . , int 2 — . . , JSON . , , .

, , -, JSON 7 Gb. , . , int. .

int. int — . , , int? , . , . , , «- ».

— : , , . — , ; . , , , .

, 10 20 , . , - , .

DEC64


, . , (, ).

, . . , Atari 2600 128 . 64 , 4 .

- . . , 50 , — ?

. , Java byte, char, short, int, long, flot, double .. , , , , . , . , . , , , . , , . This is bad.

, JavaScript . . JavaScript , . 0.1 + 0.2 0.3. . — , .

, , . , . . - , , , . . , , .

- , : , 10 , , .

. , . : , . BCD (- ). . Fortran COBOL BCD. , . Java COBOL. Java -. .

. DEC64. 64- , , .



56- , , . Intel . , . . ( , ).

DEC64 Intel x64 — , (dec64.com, GitHub ).

int. , , .

, , . , . . — , () . , , , .

, . — JSON.



Google, XML () JSON (). , XML 2005 , JSON.

, JSON . , JSON, JSON. . .

, . , . Google . Google Trends ( 2015 — . . ). JSON , XML.



, :




HolyJS Piter :


20 JavaScript: . Lea Verou, Martin Splitt, Anjana Vakil, Claudia Hernández . .

Source: https://habr.com/ru/post/327320/


All Articles