60 comments

[ 2.9 ms ] story [ 118 ms ] thread
Let nobody ever again say, "we'll ship it now and fix it once it's in prod".
It’s not like Microsoft’s culture was any better. There are stories of engineers sleeping under their desks during the browser wars. It’s a testament to JS that most don’t even remember Microsoft’s answer to it (Hint: it starts with a ‘J’ and ends in “script”)

https://en.m.wikipedia.org/wiki/JScript

I’m not really sure what the point you’re trying to make with this is? JScript was just Microsoft’s implementation of the same spec, and was by and large interoperable with JavaScript in both directions.
Parent poster said it’s bad to ship early and buggy. However, Eich won out over MS doing exactly that.
Except JavaScript is a wild success and basically all of its initial defects were eventually addressed in a backwards compatible way?
Part of what made JavaScript such a success is that there were somethings it got stunningly right despite all the thorns and sloppiness.
Please don't post shallow/snarky one-liners as first comments to HN threads. Threads are super sensitive to initial conditions, so a blank thread is like a fragile ecosystem, and a comment like this is something of an oil spill.
Sidebar to this: does anybody know if there's a full list of all the HOPL IV papers with links anywhere? A lot of them sound really interesting but I can't find them.
I tried to get hold of these but seems nearly all mentioned in this web site (in Chinese but easy to read as very light in words) are in here. Still: https://zhuanlan.zhihu.com/p/113124925

Others are seems to be referenced but embargoed (or need membership). If you can access it, please inform:

https://www.conference-publishing.com/authors.php?Event=HOPL...

Please note as mentioned by others and me that the javascript one discussed here has a new version
I'm starting to develop a theory that a person's stance on JavaScript reflects their ability to critique reasonably and therefore their maturity as a developer (to an extent).

JavaScript undeniably has some problems. It's also undeniably useful and eating the world. If you can hold both of these stances in your head and reconcile them into a nuanced opinion, then that's a great sign. If your viewpoint collapses into "JS sucks!!!" or "JS rules!!!" then you're not providing an opinion as much as a dogma, often one that is regurgitated from some other source.

I'm not saying that one should find JavaScript good or bad by the way. Someone who abjectly dislikes JavaScript but also understands its utility is quite useful. The creators of TypeScript, ReasonML, etc. all had to dislike JavaScript in some form. But they had to dislike it in a productive, nuanced manner.

Replace "JavaScript" with anything and the theory remains the same: those who can articulate and declare nuanced opinions about software they have had to interact with to a reasonable degree are able to critique reasonably.

I dislike the idea that all opinions must be in the form of productive, nuanced statements about how exactly technology should be changed in the service of 'one true set of technology'

I think it's OK for people to declare they enjoy or do not enjoy a particular technology without signaling how exactly they would change it. It's also OK to ignore or accept others opinions of personal taste. That's one of the things that enables us to have many different programming languages today, and enabled us to have JavaScript instead of FORTRANScript.

That's true, but JavaScript is something especially controversial :D. I've yet to find a programmer who doesn't have some sort of stance on JS

Also yeah it is fine to say "I don't care for JS" sans explanation. But if someone were to ask why, it'd be reasonable to expect a list of justifications that had some nuance.

I'd say that controversy is in direct proportion to its ever growing widespread use.

“There are only two kinds of languages: the ones people complain about and the ones nobody uses.”

― Bjarne Stroustrup, The C++ Programming Language

The quote is almost true, unless he didn't quantify things.

Let's say Java and PHP both have a lot of users, but I guess Java receives less percentage of complaints per 100 people. (Just a random example, if you don't agree you can substitute the two languages to suit your own experience)

So to really understand the controversy, it probably makes more sense to compare $NumberOfComplaints / $NumberOfUsers.

The point is that the rate of complaints grows when a language becomes more popular. As long as only enthusiasts and hobbyists use a language, you get relatively few complaints, because these are people who actively chose to use the language. When a language become more popular, more people will be forced to use it, more mediocre people will use it, and its shortcomings will become more apparent on larger-scale projects.
And this is why I have yet to hear anyone complain about Brainf*ck.
Which reminds of this story from the Zhuangzi. I hope it is not too irrelevant.

"Zhuangzi was walking on a mountain, when he saw a great tree with huge branches and luxuriant foliage. A wood-cutter was resting by its side, but he would not touch it, and, when asked the reason, said, that it was of no use for anything, Zhuangzi then said to his disciples, 'This tree, because its wood is good for nothing, will succeed in living out its natural term of years.' Having left the mountain, the Master lodged in the house of an old friend, who was glad to see him, and ordered his waiting-lad to kill a goose and boil it. The lad said, 'One of our geese can cackle, and the other cannot - which of them shall I kill?' The host said, 'Kill the one that cannot cackle.'"

https://ctext.org/dictionary.pl?if=en&id=2853

Whether or not someone can distinguish "I don't like thing" from "thing is bad" still serves as a useful indicator.
Couldn’t it be that I realize that JS has some problems and is undeniably useful and is eating the world, and I therefore conclude “JS rules!!!”

In my view, it lacks nuance to suggest that saying something is awesome must mean that it has no problems. :)

Yeah maybe "JS is best language ever!!!" is a better example. Or "JS is perfect!!!"
I would also state it as "hold strong opinions weakly or hold weak opinions strongly".

Unfortunately, though it requires experience to become mature, not all experienced engineers are mature. When you see problems with the tools that you have, do you rail against them because it's not what you want, or do you seek out alternatives and then build them when they don't exist?

> But they had to dislike it in a productive, nuanced manner.

No, they fundamentally rejected JavaScript, enough to build a whole new language and set of tools. This was not a subtle dislike of a few aspects of it.

Personally JavaScript absolutely terrifies me, it's a semantic mess, the equality table is one such example: https://dorey.github.io/JavaScript-Equality-Table/

I’m not a fan of loosely-typed languages in general, but isn’t that chart pretty typical for dynamically typed interpreted languages? I know PHP’s is a mess and I’ve seen comparison/equality horror stories posted to HN regarding even the venerable Python.
No, many dynamically typed languages do not perform implicit conversions: Lisp and Python are languages that do it better. They still have some subtleties (Lisp has the EQ/EQL distinction, not to mention a huge number of other quality operators in Common Lisp), but I see implicit conversions as a singularly bad idea in a dynamically typed language.
Lisp certainly performs some implicit conversions in numeric computing.

   > (+ 1 1/10 3.0)
   4.1
In this example, since + is a function, it's part of its semantics.

There would be a lot of verbiage if arguments had to be coerced to all be of the same type.

In addition to numeric examples, there are situations where Lisp is forgiving/flexible. For instance in most cases, a symbol can be used in place of a function object. The symbol is resolved to a function through its function binding.

That can be regarded as an implicit conversion, or alternatively as polymorphism.

Yet another example is that Common Lisp allows some string operations on symbols.

   (string= 'abc "ABC") -> T
No conversion ever takes place in the evaluation, as far as I know, or the passage of a value (e.g. from a function argument expression into the argument). All these kinds of things happen inside specific functions according to their respective rules.
(comment deleted)
It is trivially easy to avoid though, just use === instead of ==.

Most of the JavaScript wtf's are people getting confused by the implicit type conversions (like [] == ![]). If you ask for it, JavaScript will readily convert a string to a number or an object to a boolean. But if you don't like that, just don't rely on implicit conversions.

The average developer spends most of her time reading other peoples code, so avoiding having to understand == is a luxury most will not have.
First, it's easy to fix by just using ===.

Second, It's more of a blub programmer thing. From multiversal equality's perspective, almost every mainstream statically typed language is also a semantic mess - you can even compare int to a boolean with == in a statically typed language without having any type errors, despite the comparisons always return false and 99 out of 100 that's not what people meant.

(comment deleted)
Most mainstream statically typed languages use subtyping, that is why they permit equality comparisons of different (sub) types. But they should and do obey all the usual mathematical laws, associativity, transitivity etc.
In C++, you cannot compare unrelated types unless there's an implicit conversion or explicit equality operator (or something like that). In Rust, you cannot compare same or different types unless you implement PartialEq, and you can't compare an int with a bool. In Java, you can't use == to compare an int and a bool (both primitives).
Literally the next tab on that page shows you the results with the === operator, which is what everyone uses.

That you don’t know this shows me that you don’t actually understand JS very well. That’s fine! But don’t make and broadcast a judgement without doing the research.

> That you don’t know this shows me that you don’t actually understand JS very well.

I know about the === operator, but the original one still exists, as does all the code that was (and still is) written using it that needs to be reasoned about. That you think adding a non-obvious alternative to the language magically makes the problem go away, suggests to me that you are the one lacking understanding, not me. It was also just one example of many well documented issues with the language.

> the === operator, which is what everyone uses

Since you accused me of "broadcasting without research", I'd like to see the evidence for this claim. I just looked at the HackerNews JS and there's plenty of double equals in there.

This is the “only say cheerful things” argument. If you want to impose that at the threat point of “maturity”, then be my guest.

Don’t be surprised when any legitimate criticism just sort of dries up, however.

I don't think its physically possible to read this in the time since its been posted, but since people are commenting anyways I might as well join in.

I've been using JS since the JScript days, and let me tell you it was horrible. Awful. I would rather use VBA, Perl, early PHP, really anything I've touched besides COBOL. It was buggy, horrifically slow, had an even worse standard library than it does now, didn't work the same way between anything. I remember testing performance and getting 1000 integer increments a second in an empty for loop. Even back then an alarm clock running C was orders of magnitude faster.

But the massive popularity of the web has made it decent. Its a good example of the (overused) axiom that you can pour enough money into anything and make it good. With JS, this actually happened. Probably because the other choice was transitioning the web to Flash, Silverlight, and Java Applets. The proprietary solutions lost the battle thankfully, even though admittedly they were better than JS for a long time after they died.

There's still lingering problems, some which may prove un-fixable. The standard library is a joke. The 1 million line ancient Java monolith at work pulls in less libraries, by count and space then create-react-app. And not having threads is just terrible. People that don't know better ape over async, not knowing that most languages have async, threads, sometimes fibers, and fast shared memory between them. And NPM works decently but putting 5 million files into my node_modules folder is absurd. NPM is the only reason I know that most OS'es still have a path length limit. You would think the world could standardize on putting libraries into a zip or something like even ancient crufty languages like Java do. If it wasn't for SSD's modern JS wouldn't even be usable. And can we just compile JS already? Minification seems so normal that everyone's forgotten its a shitty hack. If you're going to minify to the point that JS resembles bytecode why not just standardize a format. People say "JS runs right away because its not compiled"... Well... How long does your WebPack take to transmogrify 150MB of spaghettified JS into a pile of chunks you can actually feed a web browser in prod? Probably longer than it takes most languages to compile. If we just compiled to a reasonable format like other VM languages, we wouldn't waste so much time parsing and keeping these tools working with every semantics update.

Here's to the hope that money poured into JS will finally fix the remaining issues. I give it another ten years and I'll finally enjoy most of my time in JS land.

The problem with establishing something like a better compressed format is that

1. it needs buy in from all the browsers or it might as well be useless

2. browsers need to bend over backwards to be backwards compatible so that you can run old web pages. if a browser does not work on all the web pages a consumer needs they will simply not use it.

3. I would bet good money that most of the management in charge of the websites that make up the web would not waste dev time on migrating to some minified JS file replacement, when webpack-style minifying works "just fine" and allows your team or whatever to keep churning out new features

> I would bet good money that most of the management in charge of the websites that make up the web would not waste dev time on migrating to some minified JS file replacement, when webpack-style minifying works "just fine" and allows your team or whatever to keep churning out new features

I don't think so personally. Code size is a huge issue for page performance, and a "bytecode" format would probably be 2-3X smaller and 2-3X faster to parse. Together, this might triple JS loading speed. Maybe double the loading speed of JS heavy sites.

JS with sourcemaps isn't so different from compiled code with debug symbols. The sourcemap support could probably be adapted with minimal work. And its likely the transition would be transparent to most users, nobody really looks at the minified JS as it is.

Another big advantage is vastly simplifying JS parsing and JIT compilation. In Java and C#, most features are added without changing the code format. And when it does get updated changes tend to be minimal. Upgrading browsers and minifiers every time JS adds a language feature is a real burden on the ecosystem

I'm not talking about convincing devs, I'm talking about convincing management that big bang refactor that hypothetically results in better performance numbers is worth the opportunity costs on new features you couldn't deliver. Or the opportunity costs of saving that money spent on devs.

The worst parts of the web do not prioritize latency numbers, so I don't see how you'd convince them that it's worth it, and any backwards-incompatible changes to the web (to force them to make the change) have historically had poor uptake from consumers, devs, and browsers alike.

> JScript ... was horrible ... I would rather use VBA

I still write both JScript (for WSH) and VBA (for my sins?) and I much prefer JScript. At least it lets you easily create your own abstractions thanks to anonymous functions, whereas VBA really fights you at every turn in this respect.

The startup penalty is because you have to run the VM itself. After all optimizations there is really no benefit in having the code in binary.
Parsing minified JS takes up quite a bit of load time for most sites. Binary formats for VM languages aren't just smaller, they're many times faster and easier to parse and verify
There are two schools 1) Load everything statically, then run the app 2) Just load enough to show the start screen, then load the rest when needed or in the background. Only the first school would see a significant speedup. eg 30% of 3s vs 30% of 30ms. I wonder however if you would be able to pre-optimize? I guess not because JS is a dynamic language.
After using many languages for a long time, and working mostly with JavaScript/TypeScript in the last years, I agree with many things that you said.

However, I think that is good to recognize the good things too:

- JS function and object notation is very flexible and nice to work with. Each time that I go back to Java I feel the pain.

- PHP makes JS look nice and consistent by comparison (note I used PHP from v3 to v5... so my comment maybe wrong today)

- Adopting functional constructs for some parts of the std lib was good. Many times I wished to have an equivalent map/filter/reduce in Python (the list comprehension syntax is terrible)

- NPM and small modules receives tons of criticism. But it allowed NodeJs to thrive. Anybody can publish or get a lib with one command. By comparison doing the same for Java was really hard in the past (you needed permission to publish to MavenCentral... and if you were lucky you were allowed after many days of mail exchanges). The situation in other languages is not better: Python package management is a mess of options, Swift package management is not mature enough.

- JS doesn’t have threads... but some languages (eg Dart) moved away from the classic threads constructs to adopt actors. If you did anything with mid complexity using Java threads and dealing with synchronized/wait you start to appreciate the simplicity of async / await.

- Template literals existed in many languages (shell scripting, Perl, etc). But in JS they can be easily extended with template functions.

- I prefer any of the Node web server frameworks over the pain of Java (I worked for many years using servlets, JEE, Spring.. and Java Rest API frameworks).

I’m not trying to do a “what aboutism” argument, just highlighting that besides the limitations there are also good design decisions in the JS ecosystem.

A lot of the newer stuff in JS is great. The baggage is what bothers me. For all the flak Java gets for having ancient stuff, the old stuff in JS is way worse.

Java cruft is better these days if you use 11+ with Lombok. Almost decent. You can also use Kotlin which is honestly good, but unless you pay up for IntelliJ support for it is mediocre at best. I really like Typescript's nominal typing, wish Java chose that road.

I'm not a Python guy, but Java has Streams and RxJava which is great for functional stuff. I'm pretty sure RxJS was originally a JS port of RxJava. The same library has flavors in most languages now, you may be interested in the Python version https://github.com/ReactiveX/RxPY

Publishing to NPM registry is much easier, but everything else is worse. I blame much of it on the lacking standard library. But JS not packaging libraries in archives, plus using minifaction instead of a bytecode format both suck. JS has a huge parsing problem, for some sites half the page load time is parsing JS. VM's with an efficient code representation like C# and Java avoid this. Java and C# package source, compiled code, and documentation in a standardized (and efficient) way. NPM just isn't there yet.

Java is missing async await, but there's also grumbles about supporting it and function coloring. Java has Akka, promises (CompletableFuture), parallel streaming, and traditional threads. The problem with supporting async/await without threads is that it doesn't solve for modern CPU's having more and more cores. In Java/C# its trivial to use the whole machine and share structures.

You should try Vert.X, its very similar to Express. I would almost dare say Express borrowed a lot from it.

There's some good design decisions rolling in, but still plenty of reasons I avoid it when I can.

Very grateful ``this`` was posted. I've been working on making my project compatible with early JS, and ``this`` is a great reference.
To appreciate the extraordinary power of modern Javascript, I think one must also be proficient in HTML/CSS/SQL. Postgresql for shared state management + Web components for code reuse/organisation + Web Sockets = blazing performance without the overhead of huge frameworks. I love: functional JS, Async/Await, Generators, Template Literals - Not so keen on Clases but if this makes it accessible to Java developers that’s good. All we need now is first classs status on IOS/Android.
What's 'extraordinary' about 'functional js', or async, or generators, or template literals? They seem alright. Nothing particularly extraordinary, though. They don't change the way I really think about problems which is what I usually classify as extraordinary.
Link is outdated. Newer version(as highlighted & linked on page) is at https://zenodo.org/record/3710954

Newer filename is jshopl-preprint-2020-03-13.pdf (published 14 March)

Older filename is jshopl-preprint-2020-03-11.pdf (published 12 March)

> There is a newer version of this record available.

A 190 page "paper" is usually called a book...
There are lots of comments and no doubt JavaScript really has its problem. But one year still I watching this and how he used mainly JavaScript to demonstrate how to think in clojure way. It is not that bad, guys

https://youtu.be/vK1DazRK_a0 (solving problems the clojure way by Rafal Dittwald).