When you hold an opinion, particularly when you know that other sane people hold the opposite opinion, it's good practice to try to come up with the best argument possible for the opposite opinion. I'm going to do that today with weak typing. I typically think that a weakly typed language is basically useless. As in, I would always prefer a language with strong typing over an equivalent one with weak typing. So in this post I'm going to try to come up with a reasonable scenario in which choosing a weakly typed language over a strongly typed one would make reasonable sense.
First, a little note about terminology. I find different people have different definitions of the terms strong and weak typing, so when I refer to these terms I am saying nothing about when the typing occurs, to me static vs dynamic typing determines whether the type checking occurs at compile time or at runtime. Strong vs weak typing determines the kind of rules that are enforced. There is obviously something of a spectrum here, but typically if you can do the following 1 + "2"
, ie. add some kind of number to some kind of string and not get some kind of error, then I would consider the language to be weakly typed. Otherwise, it is probably a strongly typed language.
So, note that you can have a weakly+statically typed language, a weakly+dynamically typed language, a strong+statically typed language, and finally a strongly+dynamically typed language. I think Python is a good example of a strongly+dynamically typed language. Most functional languages are strongly typed, some, such as Elm, Haskell, Purescript, O'caml, are statically typed, whilst some such as Lisp are dynamically typed.
Mostly, strong vs weak typing is a question of explicit vs implicit type-casts, and whether a type-cast can fail. I think casting is typically a questionable thing to allow in your language, but explicit casting does not immediately make your language weakly typed, if such casting can fail and raise an error (or crash the program). It is rare for implicit casting to fail, either it is statically typed so that it cannot fail, or it is done in a weakly typed language.
So, again, my contention is that weakly typed languages are mostly useless. Therefore today I'm attempting to come up with a good scenario in which a weakly typed language would be useful. First let's start by saying why I consider weak typing to be questionable. What should the 'value' of 1 + "2"
be? Well in order to obtain a result, you must first convert one or other of the two values, so either you end up with "12"
or 3
. Both are reasonable, some systems even attempt the latter and fall back on the former if the string does not represent a number. My point is that whatever answer is done, you could easily make the mistake of assuming one will happen when the other actually happens. Suppose you want to display the price of something including tax so you write exTax + tax
. Now suppose later you decide to display the exTax
price on its own first. Because of the way you refactor to allow this change, the exTax
is now actually a string, that has been rendered, so now when you do exTax + tax
you're adding a string to a number which may well result in cast of tax
(a number) to a string and then concatenating the two strings, obviously not what you wanted. A strongly typed system simply would not allow this mistake.
Hence you can characterise weakly and strongly typed languages as:
- Strongly typed: prevents you from making some kinds of incorrect calculations
- Weakly typed: will always allow you to present some kind of answer, even if that answer may be incorrect.
If we accept that, then to find an application suitable for a weakly-typed language is to find an application where displaying any kind of answer, even a wrong one, is better than displaying no answer. Normally calculating a wrong answer is typically much worse than not calculating an answer at all, usually we want to fail fast. For example, if you have an e-commerce store, whilst you want to normally display, say the price of a product, if there is some error you would prefer it to display either nothing, or an error message rather than display the wrong price. You certainly wouldn't want to let people buy for the wrong price, at least not if the wrong price was significantly cheaper.
However, there are situations in which calculating a wrong answer is actually better than just crashing, or displaying an error. Such scenarios I tend to think of as when you're calculating how to display the 'answer' as opposed to actually calculating the answer. So for example, maybe you already have the price of your product and are just calculating how to display that, eg. whether it should be in bold (because it's discounted maybe). In that case I'd rather it got the answer wrong and still displayed the price (bold or otherwise), rather than crashed and didn't display the price (as might happen in say a strong+dynamically typed language).
Of course such a situation could be mitigated by, for example, handling all exceptions. However, in a weakly typed language you're essentially getting that for free. In such cases, as is normal, if you choose the wrong kind of language you end up kind of implementing a crappy bug-ridden version of the correct language in your incorrect language (see Greenspun's tenth rule). So I think I can just about imagine a scenario in which using a weakly typed language would be the correct thing.
However, note that the difficulty here is in cordoning off the part to be done in a weakly typed language. It is quite tricky first calculating all of the result, and then how to display it, without some of that calculation seeping into the display/rendering code. Though one could argue that such a cordoning would be very useful. It could also be a hindrance as you may be prevented from sharing useful code.
Having defined a possible scenerio in which a weakly-typed language could be useful, I note that strongly+statically typed language could ensure that a crash never happens. That feels like the best of both worlds to me. Hence, at least for today I think I'll stick to my opinion that weakly typed system are never the correct choice. I do think the exercise is useful though, and do note that here I've only explored one possible scenerio, perhaps there are others that I'm not considering and just have never come up against. I haven't explored low-level programming, in which some kind of optimisation may be possible, though I don't think that will work in the favour of weakly-typed systems I certainly haven't thought about it enough to discount it entirely. My hope is that by performing such thought experiments, if there do exist any scenarios in which a weakly-typed language was best suited, and if I ever came across any, I might, maybe, just recognise it as such.