Quote:
Originally Posted by Shoe Lace
A good editor will catch most of those errors instantly in a dynamic language. That's my only real draw to editors like rubymine/pycharm. Their static code analysis is superb. There's a lot of comfort in knowing that you'll never ship code where you typo'd a method name or passed in the wrong number of args to a function, etc..
So take that and multiply awesomeness by a factor of 10 and you're where people are with C# and Visual Studio or Java and IntelliJ IDEA. Static analysis feels superb because you're going from nothing to something but RubyMine/PyCharm type-checking/inference is necessarily minimal and/or in many cases requires hand-written annotations. RubyMine for instance works well for Rails and Ruby standard lib because they got someone to enter all the type definitions - unless you do the same for your own codebase, you won't have the same level of confidence - it will find some trivial errors and miss others. The larger the codebase, the worse the type inference gets, because type inference is best along the surface area where you're interacting with frameworks and standard lib that the editor guys built in the type annotations for. In statically typed languages, this confidence exists by default unless you try hard to subvert it.
But getting back to the point, you can use these tools for yourself to get some of the benefit of static typing, but they are much less useful in a large team, because what needs to be annotated is not clear and the only way to get any kind of confidence that your codebase is typesafe is if you enforce coding standards (annotate everything) such that you're paying most of the cost of static typing while getting a fraction of the benefits. Again, by yourself, you know what you have to do to get the maximum benefit and minimize costs, but you will find that in a larger team, people will often do the least they need to do get the job done at the expense of others and it's difficult to communicate expectations.
Also when you get to Haskell/ML/Scala land, you can use types to express a whole lot more than just data types. The CS-ish way to look at is that type declarations are program invariants - they are statements about a program. Going backwards, tons of program invariants can be coded as types and verified statically. For example, you can design types such that user input cannot be sent directly as part of a SQL statement unless it's expliclty sanitized, values of different units cannot be used interchangeably, etc. At an advanced level, a type system can be used as a limited form of a declarative programming language that performs program verification.
https://speakerdeck.com/folone/there...-in-your-scala
http://cs.brown.edu/courses/cs173/2012/book/types.html
Now, you can do some of the same thing in dynamically typed languages, but your program will be verified at runtime and crash, instead of being verified at compile-time. The other problem is that dynamically typed languages provide much less support for encoding program invariants as types. Also, without a fairly crazy compiler, generally overusing types lead to performance penalties in dynamically typed languages that you don't incur in statically typed languages.