I am from Java world and I wonder what is so great about dynamic typing in Python besides missing errors while compiling the code?
Do you like Python's typing? Do you have an example where it helped in a big project? Isn't it a bit error prone?
I am from Java world and I wonder what is so great about dynamic typing in Python besides missing errors while compiling the code?
Do you like Python's typing? Do you have an example where it helped in a big project? Isn't it a bit error prone?
A lot of patterns (e.g. from GoF) are unnecessary or can be implemented with less efforts in dynamic-typed languages with functional flavor. In fact, a lot of patterns are "built-in" into python so if you write short and 'pythonic' code you will get all the benefits for free. You don't need Iterator, Observer, Strategy, Factory Method, Abstract Factory, and a bunch of other patterns that are common in Java or C++.
This means less code to write and (much more important) less code to read, understand and support. I think this is the main benefit of languages like python. And in my opinion this greatly outweighs the absence of static typing. Type-related errors are not often in python code and they are easy to catch with simple functional tests (and such tests are easier to write in python than in java for sure).
Static type checking is undecidable in the general case. This means that there are programs which are statically type-safe but for which the type-checker cannot prove that they are statically type-safe, and thus the type-checker must reject those programs.
In other words: there are type-safe programs that the type-checker will not allow you to write. Or, even more succinctly: static typing prevents you from writing certain programs.
This applies to all static typing in general, not just to Java.
As to Java specifically: it has a rather crappy type system. Its type system is not expressive enough to express even very simple properties. For example: where in the type of
static void java.util.Arrays.sort(Object[] a)
does it actually say that the result has to be, you know, sorted? Or that the array elements have to be partially ordered?Another problem with Java is that its type system has holes so big that you can drive a truck through:
The problem in this particular case are covariant arrays. It's simply not possible for arrays to be both covariant and type-safe.
Java combines all the hassle of static typing with none of the advantages. So, you might just as well get rid of the hassle.
However, note that this is not universal. There are other languages which have much better type systems for which the trade-offs are much less clear.
For example, here is the most stupid language benchmark of all time (Fibonacci) in Python:
and Java:
Note that there is quite a bit more clutter there, which is solely related to static typing. To make the comparison more fair, let's imagine a language with Python's syntax and Java's semantics:
[Interesting side note: with the addition of optional static type annotations in Python 3.x, that is actually also valid Python code, although it is obviously still not statically type-safe, since the annotations are just that: annotations. They are never actually checked anywhere.]
There is some definite clutter there. However, in Haskell it looks like this:
Unlike the Python version, this is perfectly statically type-safe, but there is zero type-related clutter.
In this particular case, the question between the benefits of static and dynamic typing are much less clear.
By the way, a more idiomatic Haskell version would probably look like this:
or this:
Really, the much more important difference between Java and Python is not so much that Java is statically typed and Python is dynamically typed, but rather that Java is just not a good programming language, while Python is. So, Java is just always going to lose, not because it is statically typed, but because it is crap. Comparing BASIC with Haskell, Haskell clearly wins, but again, not because it is statically typed but because BASIC is crap.
A much more interesting comparison would be Java vs. BASIC or Python vs. Haskell.
As you're from the Java world, the obvious answer would be that it's great not to be forced to write all that stuff you are forced to write, just to keep Java's type system happy.
Of course, there are other statically type checked languages that don't force you to write all that stuff that Java forces you to write.
Even C# does type inference for local method variables!
And there are other statically type checked languages that provide more compile time error checking than Java provides.
(The less obvious answers for - what is so great about dynamic typing in Python? - probably require more understanding of Python to understand.)
I suspect that the vast majority of non-trivial Java programs have dynamic typing in them.
Every time in Java that you do a cast from Object to an explicit type you are doing dynamic type checking - this includes every use of a collection class before generics were introduced in 1.5. Actually Java generics can still defer some type checking until runtime.
Every time you use Java reflection you are doing dynamic type checking. This includes mapping from a class or method name in an text file to a real class or method - e.g. every time you use a Spring XML configuration file.
Does this make Java programs fragile and error prone? Do Java programmers spend a significant part of their time having to track down and fix problems with incorrect dynamic typing? Probably not - and neither do Python programmers.
Some of the advantages of dynamic typing:
It's part of Python. Liking it in Python is silly.
Yes. Every single day I rejoice that I can make changes and -- because of Duck typing -- they are reasonably localized, pass all the unit tests, pass all the integration tests, and nothing is disrupted elsewhere.
If this was Java, the changes would require endless refactoring to pull interfaces out of classes so that I could introduce variations that were still permitted under Java's static type checking.
Not any more than static typing is. A simple unit test confirms that the objects conform to the expected features.
It's easy to write a class in Java that (a) passes compile-time checks and (b) crashes horribly at run time. Casts are a good way to do this. Failing to meet the classes intent is a common thing -- a class may compile but still not work.