I'm a big fan of PHP and it's obviously a very weakly-typed language. I realize some of the benefits include the general independence of changing variable types on the fly and such.
What I'm wondering about are the drawbacks. What can you get out of a strongly-typed language like C that you otherwise can't get from a weakly-typed one like PHP? Also with type setting (like double($variable)), one could argue that even a weakly-typed language can act just like a strongly-typed one.
So. Weak-type. What are some benefits I didn't include? More importantly, what are the drawbacks?
The cited advantage of static typing is that there are whole classes of errors caught at compile time, that cannot reach runtime. For example, if you have a statically-typed class or interface as a function parameter, then you are darn well not going to accidentally pass in an object of the wrong type (without an explicit and incorrect cast, that is).
Of course, this doesn't stop you passing in the wrong object of the right type, or an implementation of an interface where you've given it the right functions but they do the wrong things. Furthermore, if you have 100% code coverage, say the PHP/Python/etc folks, who cares whether you catch the error at compile time or at run time?
Personally, I've had fun times in languages with static typing, and fun times in languages without. It's rarely the deciding issue, since I've never had to choose between two languages which are identical other than their kind of typing and there are normally more important things to worry about. I do find that when I'm using statically typed languages I deliberately "lean on the compiler", trying to write code in such a way that if it's wrong, it won't compile. For instance there are certain refactors which you can perform by making a change in one place, and then fixing all the compilation errors which result, repeat until clean compile. Doing the same thing by running a full test suite several times might not be very practical. But it's not unheard-of for IDEs to automate the same refactors in other languages, or for tests to complete quickly, so it's a question of what's convenient, not what's possible.
The folks who have a legitimate concern beyond convenience and coding style preference are the ones working on formal proofs of the correctness of code. My ignorant impression is that static type deduction can do most (but not all) of the work that explicit static typing does, and saves considerable wear and tear on the keyboard. So if static typing forces people to write code in a way that makes it easier to prove, then there could well be something to it from that POV. I say "if": I don't know, and it's not as if most people prove their statically-typed code anyway.
changing variable types on the fly and such
I think that's of dubious value. It's always so tempting to do something like (Python/Django):
user = request.GET['username']
# do something with the string variable, "user"
user = get_object_or_404(User,user)
# do something with the User object variable, "user"
But really, should the same name be used for different things within a function? Maybe. Probably not. "Re-using", for example, integer variables for other things in statically typed languages isn't massively encouraged either. The desire not to have to think of concise, descriptive variable names, probably 95% of the time shouldn't override the desire for unambiguous code...
Btw, usually weak typing means that implicit type conversions occur, and strong typing means they don't. By this definition, C is weakly typed as far as the arithmetic types are concerned, so I assume that's not what you mean. I think it's widely considered that full strong typing is more of a nuisance than a help, and "full weak typing" (anything can be converted to anything else) is nonsensical in most languages. So the question there is about how many and what implicit conversions can be tolerated before your code becomes too difficult to figure out. See also, in C++, the ongoing difficulty in deciding whether to implement conversion operators and non-explicit one-arg constructors.
I have been using both strong typed (like Java) and weak typed (like JavaScript) languages for some time now. What I have found is that the convenience of the weak typed languages are great for small applications. Unfortunately, as the application grows in size, it becomes impossible to manage. There becomes too much to keep track of in your head and you have to start depending on your IDE and the compiler more and more or your coding grinds to a halt. That is when strong typed languages start to become more useful - with the application grows very large.
Two examples that constantly drive me nuts in the weak typed JavaScript are using external libraries that are not thoroughly documented and refactoring.
External libraries: When dealing with a strongly typed language, the code from the library itself provides self documentation. When I create a variable of type Person, the IDE can inspect the code and tell there is a getFirstName(), getLastName() and getFullName(). In weak typed languages, this is not the case as a variable could be anything, have any kind of variable or function and have function arguments that could also be anything (they are not explicitly defined). As a result, a developer has to lean heavily on documentation, web searches, discussion forums and their memory of past usages. I find it can take hours of looking things up in JavaScript for external libraries while with Java I just hit the "." key and it pops up all my options with documentation attached. When you encounter libraries that are not 100% fully documented, it can be really frustrating with weak typed languages. I recently found myself asking "What is argument 'plot' in function 'draw'?" when using jqplot, a fairly well but not completely documented JavaScript library. I had to spend an hour or two digging through source code before finally giving up and finding an alternative solution.
Refactoring: With strongly typed languages, I find myself able to refactor quickly by just changing the file I need to change and then going to fix the compiler errors. Some tools will even refactor for you with a simple click of a button. With weak typed languages, you have to do a search and then replace with care and then test, test, TEST and then test some more. You are seldom entirely sure you have found and fixed everything you broke, especially in large applications.
For simple needs and small applications, these two concerns are minimal to non-existent. But if you are working with an application with 100's of thousands or millions of lines of code, weak typed languages will drive you nuts.
I think many developers get upset about this and turn it into an emotional discussion is because we sometimes get it in our heads that there is one right and one wrong approach. But each approach has its merits - its own advantages and disadvantages. Once you recognize that you set the emotion aside and choose the best for you for what you need right now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With