I don't think dynamic typing has any benefit.
I have tried the usual dynamically-typed languages, in particular Python, Javascript, Ruby and Lua, and so far have only found dynamic typing a hindrance, especially if a project grows to any adequate size. It may be non-idiomatic, but I usually end up writing a make-shift runtime type system for each function manually, i.e. type-check all parameters, make sure values are in the correct range, make sure return value is correct, etc. Most of the time, not having type checking doesn't introduce bugs, per se, since the usual problems that I will encounter will be obvious, but they are damn annoying. Some of the most irritating of these (taken from my experience with Python) are:
- Forgetting to add '()' after a function name, so I assign the function to a variable instead of the result of running it
- Forgetting to actually return a value from a function (which results in that function always returning 'None' which isn't great if that was intended to be a valid return value for that function)
- Forgetting that I actually used a name for another variable of a different type, which gets overwritten
- Overwriting a built-in function (I mean, great, that's really powerful, but I don't see the benefit)
As a consequence, I will generally only use such languages for small scripts, programming challenges, hacks, and just generally small or simple programs that I don't intend to maintain. Change my view, and let me know why we need dynamic types, and why Python/Javascript/Ruby/Lua/etc. made the right choice with using this system.
Edit: I'm adding another irritation I've remembered after reading Jon Skeet's post (link in comments), which is:
- Forgetting what functions actually do (this applies somewhat to variables as well)
In statically typed languages, you can usually learn a lot from what types the parameters of a method are and what its return type is - knowing what I'll be getting back can usually tell me a lot, for instance, maybe the readlines() method which I'm expecting to return []string actually returns string. I'll actually have to check the documentation to confirm behaviour with a dynamically typed language, but if I make an incorrect assumption in a statically typed language the compiler will save me, and even tell me what type I'm getting if I have access to neither the documentation nor the source code of the method.
Having said all this, I also remembered one area where dynamic typing works astonishingly well in my opinion, and no amount of static typing or type inference will benefit, and that is:
- Reflection
Reflection, in the few times that I've tried using it, is one of the few times when I'm actually battling against the type-checker to get things to work. It's actually a pleasure in Javascript to be able to trot all the way through the variables and methods implemented by a prototype, find the one you want, and get the result you want simply by giving the name of the variable/method you want at runtime. That said, I feel that reflection is such an unsightly, unmaintainable mess that the more deterrent I have from using it the better. Why do I feel this way about reflection? I feel that it's again because of the lack of types; you basically have to type-check everything that you're using at runtime, undoing all the hard work that the type-checker performed at compile time to make sure that the objects you'll be using behave.
Edit: Another benefit of static types is that you can often learn a huge amount about function simply by inspecting the types of the parameters and return values; Haskell has a resource, Hoogle, which allows you to find a function by name, but also by its type signature. Despite thinking that it was a niche, proof-of-concept feature when I heard of it, I have actually used it to great effect.
Being able to see the types of a function is very nice in documentation too, where you don't have to read the description of a function to find out what type of parameters it takes and values it returns, like you do with languages like Python (some languages get over the documentation issue by describing the types in function comments, like Ruby and some PHP codebases, such as Wordpress).
Posted May 11, 2013, 7:52 PM UTC · edited
I've written large complex 10,000-file sized programs in dynamically typed languages and I agree with you. Static type prevents entire classes of bugs, makes refactoring easier, makes reading and understanding code easier, etc.
But some languages have incredibly weak and verbose static type systems that are frustrating to work with. But if you are working with a statically typed language with great generics and type inference, then it's actually very comfortable.
I'd like to see more languages have optional dynamic typing or optional static typing. Then you could choose how explicit you want to be and use the same language for small scripts and large projects.
In a sense, many statically typed languages essentially have optional dynamic typing:
Very true; in OOP, if you just specify that every parameter type and return type is Object, you effectively have a dynamically typed system.
Except for all the extra boilerplate casting. The only language I've seen so far with true boilerplate-less optional dynamic typing is C#.
Even in C# it breaks down once you get to higher order functions. The state of the art is typed racket & contracts.
No, you don't. Because you have to cast that object back to something to use it. In a dynamically typed language, you can call methods on untyped
Objectinstances without having to give them a type first.True, I forgot about that; I believe this argument applies to the parent comment as well in that case, except instead of casting you have pattern matching?
The idea of optional dynamic/static typing is a nice idea, but like any freedoms I can imagine it would get heavily abused by people who don't really know what they're doing or just generally lack discipline. I think it would also introduce an unnecessary verbosity, even for what was intended to be a small script (unless dynamic typing was the default).
That's not an argument. Good programmers will make good code, and bad programmers will make bad code, regardless of the language.
That said, if it's easy to make bad code, it's actually a good thing: It allows you to detect bad programmers, and get rid of them, faster.
True, but if it's easy to write bad code in a language, I believe that quite often the language will get blamed; I find C a lovely language to write in sometimes, but it is far too easy to shoot yourself in the foot with it and that's the part critics hone in on, despite how many unit tests and good practices you impose on your own code base.