Saturday, September 8, 2012

What if Python had a strict mode

Python, our most-beloved byte-code interpreted language, recognizes only a few errors during compile time. Being a dynamic language, it simply doesn't see errors until the interpreter tries to run the code, only to find out that it isn't going to work, and throws an exception. This delayed nature of giving an error can be very frustrating. A Python code may run alright for weeks and then suddenly go BOOM as it runs into an exception. Wouldn't it be nice if Python could catch trivial programming errors at compile time? What if Python had a strict mode?

Perl, ‘that other’ byte-code interpreted language, has a strict mode in which the compiler is, well, more strict about code constructs that may well be programming mistakes. In Python, there is no such thing as a strict mode. But suppose there was, what would it be like? It would surely be nice if the following could be caught at compile-time.
  • syntax errors, including indentation errors;
  • undeclared local variables: this expresses the need for a local keyword that declares local variables. Alternatively, Python could have an operator := that declares and assigns a new local variable, like Go has. (In addition, do away with the global keyword. New variables outside a function should be treated as global in that module or class scope);
  • stricter type checking: reusing a variable as a variable of a different type is an error. This would eliminate the bad coding style of reusing the same variable name for a different purpose;
  • type errors: certain operations can't be done on certain types; e.g, the divide operation does not exist for the string type;
  • format string checking: check the number of arguments for format strings;
  • format string checking: check the types of the arguments for format strings.
Note that these suggestions would change Python from a dynamically typed language to a statically typed one — which is something we would like to avoid. On the other hand, it paves the way to more far reaching changes:
  • strict checking of function parameter types: function parameters should specify type;
  • strict checking of function return types: functions should have a return type.
Python does have typing, but you seldom explicitly state the type of a variable. There are a few cases where you do explicitly specify the type. For example, when creating a new class: class MyType(object) declares a class of type MyType with parent class object. When catching an exception, you specify what type of exception: e.g. except KeyError.

Wrapping up
Python is a dynamically typed language. This is one of its key strengths; you can do things in Python which are not possible in other languages due to their typing restrictions. The dynamic nature of the language allows for quickly throwing some code together. However, particularly for maintaining larger codes this becomes more of a problem. Python does not offer the option of having a strict mode, like there is in Perl. I feel that Python could benefit from having a strict mode.

A lint-like tool for checking your Python code is PyChecker.