Refactoring to maintainability

A quick review of Javascript

The setup

Anyone that has spent anytime with me would have learned that I am not fond of Javascript, I consider it a bad language. Last week I was discussing about it, again. So here are a couple of things on this regard.

The core

My biggest issue with Javascript is that is a dynamic weakly typed language.

Let me define a couple of concepts here:

  • Dynamic: there is no check of types (parameters, variables, returns, …) at compile time (maybe there is no compile time at all)
  • Static: there is a check of types at compile time
  • Strong: the piece of memory referenced by a parameter or variable can only be manipulated as the same type as it was declared
  • Weak: the piece of memory reference by a parameter or variable can be manipulated as a different type.

Let me draw this image here:

Four possible type of languages

Four possible quadrants, one example for each (easy for you to find other examples).

Strongly typed languages, are good. Either dynamic or static, you can know what you are working on, and any kind of change needs to be explicit (remembering Python’s mantra of explicit is better than implicit)

Static weakly typed languages still force you to be explicit at the changes.

And we are left with dynamic weakly typed languages, which surprise you because suddenly you have results that don’t seem to make sense.

I have to point out that the strong/weak is not a binary proposition, but a sliding quality. After all, a language like Python has some implicit conversion (int to float, for example). And Javascript doesn’t have the full ability that C has for example, using void *

Still, the combo dynamic/weak is where you don’t want to have a language. A lot of gotchas and wats exist because of implicit conversions that should not be there.

I don’t even like conversions from int to float.

Null and undefined

Tony Hoare famously calls Null his billion dollar mistake. Javascript went Hold my Beer and added undefined

Closures

Closures are awesome, and allow for really interesting constructs. There are two ways to close over variables: you either close over the value, or over the reference. And, currently, I think that the later is the wrong option. When closing over a value is easy for me to read a piece of code and understand what is going on and what I will expect to happen. But when closing over a reference, I cannot infer anything about behaviour, because until runtime I will not be able to know what is being referenced.

This

The this keyword in Javascript has its own issues because the meaning is overloaded. In most OOP languages, this (or equivalent) represents the current instance of the object. FP languages, there is no concept of this (not 1005 true, but close enough). But on Javascript you can use this anywhere and the meaning changes depending on where it is being used.

Javascript never heard of the principle of least surprise.

Environment

This is one that annoys me to no end. But I have to say, I think that is a combination of factors that lead to it, which are not necessarily the fault of Javascript. Javascript started as a simple scripting language for the web. When I mean simple, is just small scripts inlined in the page. And the alternatives were the doomed VBScript (which only worked on Internet Explorer) for small scripting, and for creating web apps you had Java Applets (which was sloooooooooooooow).

The explosion of the web comes, and there is only one game in town. Being the only option available is very, very different from being a good option. So now you get a lot of people starting on a new (bad) language, which has no support for anything, and people started to fill that void. This would have happened with VBScript, or any other scripting language that had been the dominant language at the time.

And the way that they were filling that void … is not ideal from a business perspective. For personal work and experimentation it was good, small libraries that only have what you care about. But millions of small libraries are … complicated to manage, especially from a security standpoint of view. One reason I have been given before is that with small libraries you only add what you need, which is important for the amount of code that needs to be transmitted to the client. The idea I agree with, the implementation … C/C++ linkers have been, for ages, removing unused references. And basically is what transpilers do too.

And that points to another issue, seen on NPM, which is ignoring history (common malaise of our profession … hmmm … common malaise of humanity). Dependencies are complicated, to keep the right version and avoid classes. There has been lots of work in this area by multiple languages. NPM when YOLO, and that is how you ended with the node_modules directory and this joke:

Heaviest objects in the universe joke

The good parts

I can’t say that everything is wrong with the language, nor I can fault the creator for some of the issues, due to the well know fact that suits got in the way. Designing a language is difficult. Do it in the small amount of time given … and is better than I would have done.

I like the fact that originally was a prototype-based language (if you want a good representation of this paradigm, give a try to io), although I did not realized that for a long time.

Because originally it was based on Scheme, functions are a first-class construct. Some of the things that I consider powerful about JS comes from this proposition.

For its original idea (small scripts), being a dynamic language was a good selection.

Typescript and other transpilers

I was asked, what do you think about Typescript? So let’s use the same answer that I gave: first, I do love the work of Anders Heljsberg. I consider Turbo Pascal, Delphi and C# as great languages (not perfect, that I haven’t discovered yet). But Typescript has a big issue for me: it is a superset of Javascript. So every issue present in JS is present on Typescript, but you are trying to apply a new set of rules on top of it to alleviate those issues (I’m going to go with the Spanish idiom of Aunque la mona se vista de seda, mona se queda).

Typescript is hitting its stride substituting Javascript as the language of choice for business systems.

But Typescript is not the only option. Purescript, ClojureScript, Rescript, Fable … there are really good options out there. Languages that have much better foundations than Javascript.

But it all gets translated to JS anyway?. And all code gets translated to assembly. And yet, who knows or remembers assembly? I haven’t touched it since university.

Conclusion

All of the above are my (strong) opinions of the language. But, can you create good applications/code with it? Of course. Can you create bad applications/code with languages that I consider better? Well, I know I have done that. But the less I need to fight and protect myself against the language, the better. If I need to use it because is already present in a system that I need to work in, I would use it. But I know that I would not start any project using Javascript.