Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with Python ~ static typing? [closed]

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?

like image 853
Etam Avatar asked Sep 01 '10 19:09

Etam


People also ask

Can you enforce typing in Python?

Python will always remain a dynamically typed language. However, PEP 484 introduced type hints, which make it possible to also do static type checking of Python code. Unlike how types work in most other statically typed languages, type hints by themselves don't cause Python to enforce types.

Does Python use static typing?

There are two types of programming languages: Statically typed and dynamically typed languages. Python is a dynamically typed language. You don't have to explicitly specify the data type of variables. The same is true for functions: You don't have to specify the type of arguments or the function's return type.

Why is duck typing used in Python?

The main reason for using duck typing is to provide support for dynamic typing in Python programming. In Python, we don't need to specify the variable's data type and we can reassign the different data type values to same variable in further code. Let's see the following example.


2 Answers

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.

like image 51
Jörg W Mittag Avatar answered Oct 24 '22 21:10

Jörg W Mittag


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.
like image 36
Dave Kirby Avatar answered Oct 24 '22 22:10

Dave Kirby