views:

349

answers:

7

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: 

It's a load off your mind. You can think the color red as "Red" (a constant) as "255, 0, 0" (a tuple) or "#FF0000" (a string): three different formats, that would require three different types, or complex lookup and conversion methods in Java.

It makes code simpler.

Beau Martínez
A: 

For example, you can write functions to which you can pass an integer as well as a string or a list or a dictionary or whatever else, and it will be able to transparently handle all of them in appropriate ways (or throw an exception if it cannot handle the type). You can do things like that in other languages, too, but usually you have to resort to (ab)use things like pointers, references or typecasts, which opens holes for programming errors, and it's just plain ugly.

leoluk
http://en.wikipedia.org/wiki/Tagged_union
KennyTM
A: 

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.)

igouy
It is not just about type inference ( which can also be statically typed ) but the fact the type is known until runtime. ie `hello( self, object ): .... ` the type of object is know until runtime, in python.
OscarRyz
@OscarRyz >> the fact the type is known until runtime << Do you mean not known until runtime?
igouy
@OscarRyz >> which can also be statically typed << That's why I wrote "there are other statically type checked languages that don't force you to write all that stuff that Java forces you to write" and "Even C# does type inference for local method variables!"
igouy
+3  A: 

Do you like it in Python?

It's part of Python. Liking it in Python is silly.

Do you have an example where it helped in a big project?

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.

Doesn't it a bit error prone?

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.

S.Lott
+16  A: 

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:

String[] a = new String[1];
Object[] b = a;
b[0] = 1; // ArrayStoreException

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:

def fib(n):
    if n < 2: return n
    return fib(n-2) + fib(n-1)

and Java:

int fib(int n) {
    if (n < 2) return n;
    return fib(n-2) + fib(n-1);
}

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:

def fib(n: int) -> int:
    if n < 2: return n
    return fib(n-2) + fib(n-1)

[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:

fib n
  |     n < 2 = n
  | otherwise = fib (n-2) + fib (n-1)

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:

fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)

or this:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

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.

Jörg W Mittag
+1 I really need to get on learning Haskell
aaronasterling
+1, may I suggest going easy on the overall anti-Java (or even anti-BASIC) theme of your post? It presents convincing arguments, but using expressions like 'crappy', 'holes so big that you can drive a truck through', 'just not a good programming language' are not really adding anything to an already good answer.
MAK
As a Python programmer I would not write a recursive fib function - it is massively inefficient unless you memoize the results. In Python it is simpler and more efficient to write it as a loop.
Dave Kirby
+1 lets not pretend that we can be statically typed without being strongly typed
gnibbler
>> rather that Java is just not a good programming language, while Python is << For some definition of "good". For some other definition of "good" like $$$ made by programmers and corporations and ... the assessment could be different.
igouy
@gnibbler: Huh? It's perfectly possible for a language to be statically yet weakly typed -- C is usually the canonical example of such a language.
Daniel Pryden
@Daniel, Of course terms such as "statically typed" are open to interpretation, however I would not consider C to be truly statically typed because it is possible to work around the type system using casts/unions etc.
gnibbler
@igouy, sadly good != lot of $$$. In fact quite often the opposite is the case
gnibbler
As I understand it, the term for that difference between Java on one side and Haskell or Python on the other is explicit typing vs. implicit typing. Dynamic typing is still more flexible, but implicit static typing is a perfectly good compromise. (I'm a Python-head who takes advantage of dynamic typing regularly but I still think that the biggest flaw in languages like Java and C/C++ is the distracting clutter of explicit typing)
ssokolow
@ssokolow: Yes, that's right. Note that C# 3 and C++0x actually do provide implicit typing via type inference, although in both cases you actually have to *explicitly* tell them to use *implicit* typing via the `var` and `auto` keywords, respectively.
Jörg W Mittag
@igouy: the Java language designers spends a lot of money for advertising the language as the next generation language that everyone should use, and they forgot to spare some for actually designing the language.
Lie Ryan
@Lie Ryan: Yup. After all, Sun spent so much money on PR, they went bankrupt. Twice. It's really sad, comparing the talent of the people who worked on Java with the result: Guy L. Steele, Jr. (creator of Fortress, co-creator of Scheme, editor of the Common Lisp specification, and general Lisp genius), Phil Wadler (co-creator of Haskell, creator of Links, and the man who brought category theory and monads into the programming world), Martin Odersky (creator of Scala, Pizza and Funnel), Gilad Bracha (creator of Newspeak, Strongtalk and general Smalltalk genius) to name just a few.
Jörg W Mittag
+7  A: 

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:

  • Greatly reduced reliance on inheritance. I have seen Java programs with massive inheritance trees. Python programs often use little or no inheritance, preferring to use duck typing.
  • It is easy to write truly generic code. For example the min() and max() functions can take a sequence of any comparable type - integers, strings, floats, classes that have the appropriate comparison methods, lists, tuples etc.
  • Less code. A huge proportion of Java code contributes nothing to solving the problem at hand - it is purely there to keep the type system happy. If a Python program is a fifth the size of the equivalent Java program then there is one fifth the code to write, maintain, read and understand. To put it another way, Python has a much higher signal to noise ratio.
  • Faster development cycle. This goes hand in hand with less code - you spend less time thinking about types and classes and more time thinking about solving the problem you are working on.
  • Little need for AOP. I think there are aspect oriented libraries for Python but I don't know of anyone that uses them, since for 99% of what you need AOP for you can do with decorators and dynamic object modification. The wide use of AspectJ in the Java world suggests to me that there are deficiencies in the core Java language that have to be compensated for with an external tool.
Dave Kirby
+2  A: 

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).

Mike Korobov