Application development Methodologies Wisdom

About The Software Craft and Tool Choice

    In software, as in other more traditional trade, the choice of the tool defines artisan.

    You can tell quite a lot about someone who concretely forms a new product with hands, from the tools he or she decides to use. If you ask, for instance, a cook, about knives, you will find out that really good cooks, chefs, tend to be rather opinionated about blades and have a collection of different knives which they use for very specific tasks.

    In software, we have developers asking on Quora questions such as “which is the software language which allows me to earn more straight out of the University?”, or “would language XYZ a good choice for someone who has no experience about programming?”.

    Terrible questions lead to not so good answers and debatable choices.

    In recent years, we have seen Javascript, which was designed for web front end, being recycled as a back end language, due to the fact that “being able to use the same tool for both purposes would be an advantage”.
    Actually Javascript is a not so good tool which is pretty much the compulsory choice on the browser, as it is the native language of the browser. But on the server you can have a choice, and do your development using a multitude of different approaches.
    Should you use the same language, even in contexts where it arguably does not naturally belong?

    Arguably Javascript is a language which does not lead the programmer to think about the problem at hand, as the language itself is full of unintuitive and not easily rememberable traps.
    You have to constantly be aware of the way the language works, and test every outcome at every step, to be sure you did not overlook anything.

    Some examples have to be provided to make this point.

    Suppose that you are testing 1 < 2 < 3.
    Does that expression evaluate to true? Of course, you would say, it is mathematically obvious…
    And now what about testing 3 > 2 > 1 ? Is it still true?
    Nope, if you try it inside the Javascript console in, for instance, Chrome, you will get false.
    How is it possible, you got the first result correct! Actually, that first result being correct is purely coincidental. The first comparison, in that case is 1 < 2 which evaluates to true, and true is converted to 1 (one) before proceeding with the next comparison with three.

    Is 1 less than 3? Yes, therefore, true… But that logic is broken and does not work in the second case: 3 > 1 returns 1. Is 1 less than 1 ?
    No. therefore 3 > 2 > 1 == false. Are you feeling just a tiny bit uneasy?

    Javascript is so full of bad parts, that you have to read a book “Javascript the good parts” in order to choose a subset of the language which is more or less safe to use.

    Surprises in Javascript abund, there are actually lots of entertaining videos and web pages on the subject that there is actually a genre, programming humor, describing them.

    A few interesting and amusing ones:
    [] + [] == “”

    [1,2,3]+[4,5,6] == “1,2,34,5,6”
    Notice the conversion to string, which concatenates the wrong items.
    You could think you could get a slightly better result by using a comma after the third element of the first array. Try it and see if the result gets any better… It does not.

    Also: [] == false evaluates to true.

    Also [] == “” evaluates to true.

    But !![] evaluates to true, while !!“” does not. Were you betting on being able to apply the same logical algebraic operation on both of the sides of the equation without it changing its meaning?
    Also, [] == [] interestingly, evaluates to false

    So, it is apparent that Javascript is a language on which any non-trivial logical computation can become problematic and fraught with unexpected results.
    If you deal with numerics, you soon see that Javascript completely lacking integers and converting literally everything to IEE-754 floating point numbers is another source for problems.
    E.g.: 0.1 + 0.2 == 0.3 evaluates to false as its result is 0.30000000000000004
    Rounding errors anyone?
    And the automatic conversion between numbers and string causes more mayhem:
    ‘2’ + 1 becomes ’21’ (It first convert the second operand to a string, then it concatenates the two strings).

    Sometimes the string concatenation behaves more or less in a sort of understandable way, e.g.: You can have “wtf” + 1 resulting in “wtf1”.
    Nice, but of course it won’t work for subtraction, therefore “wtf” – 1 will result in NaN, not a number. It is very amusing, but not the most problematic situation.

    The type system is so dependable that Array instanceof Array is false…

    What are the consequences of all this amusement? The consequences are that the language is pretty much very difficult to use properly and reliably without a linter, an external utility assuring that you are not using a problematic construct.
    You also need to test extensively, but you should do that anyway, with any language.
    With Javascript, however, you can’t just depend on the formal exactness of formula and need to test potentially every step of it.

    Therefore, it is difficult to find a seasoned back end professional who would like to use Javascript as a language of the first choice for back end programming.
    Normally seasoned professionals want tools which just respond, quickly and predictable, which are so gentle with its holder to warn him if he or she is doing something which might result in a wrong result.
    These more traditional languages often are very pedantic on conversions, and would not cast a number into a string or vice versa, without the programmer being informed…
    Some of them might also have strict type rules, further limiting the room for programmer mischief and excessive creativity.

    When it comes to inheritance, Javascript diverges very radically from all other object-oriented languages, offering multiple ways of doing it, which can cause many other entertaining issues.
    And memory issues, are rampant, with little if nothing, in terms of tools allowing to prevent them.
    NodeJS applications are often so unstable, that often you need to reset automatically the server whenever it becomes non-responsive. This is such a common problem that there specialised monitors able to do just that are quite common. It is common, for some of the steadiest applications developed with traditional languages on very stable operating systems, to be able to work for years without ever requiring a reset.

    Even without taking performance into consideration, in my rather informed view, software developed in Javascript is considerably more expensive to maintain compared to more rigid and disciplined languages. At least it is so for any large scale application, and it is doubtful that NodeJS is a good choice for considerably complex applications, or for applications which might need to scale up and become more complex and larger with time.

    As Robert Martin writes, whenever we software developer say something like “I will fix it later”. Most of the times we do it, we lie: That tomorrow never comes and things remain broken, provided they (barely) work.
    A worse lie than that is “this is just a prototype, we will throw this away as soon as we get funding”. That prototype is going to haunt you for many years if you are lucky enough to be successful.

    Using the right tool for the job is a matter of ergonomics, ultimately, it is a matter of economics, and running costs of a project.