It is really hard to write good software in Javascript
Six years of building Golang services gave me fewer race conditions than one year of writing Javascript. I have spent that year on vidstudio.app, an in browser client only video editor, which means I have had to write a lot of Javascript and have come to the conclusion that it is in fact a challenging language to master. The worst part is how easily I got there. Most of those races I introduced without noticing, and the one I saw coming is the one that taught me the most, because catching it is what let me say concretely why Javascript is so hard to write well. I was reworking the export pipeline of the editor and had to replace one of my dependencies which was part of the export path. For context, my export has to demux a source file, read a section of it, decode it, draw it, apply some effect, encode it and finally assemble it, and the order of assembly in a media file is important. The dependency I wanted to replace was mp4box.js, better known as a demuxer but perfectly capable of muxing, where you hand it an encoded chunk and it synchronously consumes the chunk. That synchronous consume was doing more for me than I understood at the time. Because the call returned when the work was finished, the loop handing over chunks in order was also the loop that had finished writing them in order, and I never had to think about either property. The new muxer, mediabunny, hands you back a promise instead, which resolves when the pipeline is ready to receive more data. The call no longer tells me that the previous chunk has been dealt with, and the sequencing I had been getting for free turned into something I had to state out loud. I am really glad I caught this one myself, but I still had to deal with serialising the assembly of the file, and while working on it I thought that this would never have happened to me in Golang. The reason this would never have happened to me in Golang, C++, C# or Java is that by default you get linear program execution. The order in which I invoke the lines of code is the order they execute, and the only time that changes is when I decide to go non linear. That is a convention rather than a guarantee, since a library in any of those languages can spawn threads without telling me, but it is a strong enough convention that a library doing it silently is considered badly behaved. In Golang I decide for myself to spawn goroutines and complicate the execution flow of my program in exchange for scalability. Javascript has no such baseline. Anything that touches I/O is asynchronous whether I want it to be or not, and in the browser there is no synchronous version to fall back on, so if I need operations linearised I have to arrange that myself. I suspect this is why the steady pipeline of articles trying to explain the event loop is still very much active, and still eagerly consumed by the next generation of developers, just as I consumed them when I first crossed paths with Node.js. Nobody is publishing a fresh explainer every month about how a for loop executes. Now that I am using Javascript more frequently I can see how challenging it is. It really does take effort to write good and correct software while staying conscious of every I/O operation in your application. I take linear execution for granted in my day job, and on my side project I have to actively classify which parts of the application have to stay linear and which ones can be left to run in whatever order the event loop decides. The event loop is a powerful concept and I am not arguing that it should not exist. I am saying that it hands me a job that other runtimes do for me, and that the job never finish. If you are interested in the project check it out Here: video-editor and Here:text-based video editor For further actions, you may consider blocking this person and/or reporting abuse Top comments (0)
Comments
No comments yet. Start the discussion.