My irrational fear of Python

Started by
26 comments, last by MDI 16 years, 11 months ago
Skip to the last paragraph for my question. Everything else is just background stuff :) I've just completed a major project in C++, and am now having a bit of a language crisis. The project made use of many external libraries, each using their own wildly differing conventions for code style, string types, error handling and so on. It dealt with multithreading, which proved to be unnecessarily troublesome. It needed to use Unicode for all strings, something that the STL appears to be somewhat undecided on. It used dynamically loaded code, which also required some quite disgusting code to get working in a cross-platform fashion. This dynamic code was used to enable plug-ins, which due to a variety of C++ oddities, also required some disgusting code to get working. All these things made me despise C++, and by the end of the project I was more than ready to make the jump to another less horrible language. I'd heard many many good things about Python, and liked what I read about it. I figured I'd give it a try, it seems like I'll be able to write programs much faster and spend less time faffing around. So I went in search of some tutorials and got myself an IDE, and had a go... It didn't last long, though; I got scared by what I saw. I get thoroughly dazed and confused by dynamic typing, it seems. I'm used to specifying a type for everything and letting the compiler tell me if I've done something wrong. I don't like the idea that I can call my function that's expecting an int with a string... I don't like the lack of control, the lack of specification, the lack of safety... I'd like for there to be a stronger guarantee about the running of the program than the comments above methods to say "only call this method with a string". It's scary! After investigating C# (another story) and not liking what I saw, I sat down and had a good think about what I actually want from a language. In the end I figured I'd actually like some kind of executable formal language, something that could specify my intentions exactly and leave nothing to chance. Perhaps that discussion is for another time though. Anyway, I suppose I'm posting this to ask for advice on how to think. I'd like to use Python as I'd like to write programs quickly, but I don't seem to be in the right mindset. How do you chaps that use dynamically typed languages cope with it? How do you justify the apparent lack of safety and verifiability? Is extensive unit testing enough to get you by? Or do you just not care?
Advertisement
Exceptions.

People who come from too rigidly statically-typed a background tend to think of Exceptions only as types, themselves, for the sole purpose of handling out-of-bounds behavior. They've been told that exception handling is expensive, due to all that stack unwinding, so they minimize its use and try to localize it as much as possible. Plus, their code rarely has sufficient information to handle an exception at point of occurrence, so it gets rethrown to a larger scope that has the requisite details.

In Python, it's almost completely opposite. Exceptions are cheap, and are an excellent way to add robustness to your code. Yes, you should unit test, and you should write your tests first (test-driven), but you can validate parameters or recover gracefully from errors by using exceptions. More importantly, you start to realize that it is not the specific type of the argument that is often important, but support for the required operations (incidentally, this is what C++ templates provide, for non-metatemplate uses, albeit in a static typing framework).

Besides, your C++ programs weren't that safe just because you lined the types up right. C++ is better than C in terms of allowing automatic type conversions, but type coercion is still trivial in C++. Type coercion is impossible in Python; you can only perform type conversion through explicit method invocation. (The common counter example of passing an int where a string is expected is actually wrong; it only works where there is an acceptable operator overload, such as in print statements - int.__repr__() is called - or string concatenation - int.__str__() is called.)

Like you correctly identify, it's a different mindset, and you have to acquire it on your own. My advice is to write programs that solve progressively harder problems, but don't write translations of C++ approaches. Learn the idiomatic Python way, and see how they take advantage of the language's strengths to provide comparable to superior levels of reliability and verifiability, and consistently superior levels of flexibility.
Out of curiosity, why didn't you like the looks of C#? It handles plug-in style situations well, has a large standard library with consistent conventions (and libraries for it tend to better follow convention), does unicode everywhere painlessly, threading fairly well...

If you have high cross platform requirements... well sure; it's not there yet. If you're scared by the JIT/garbage collection bugaboo, that's just the same sort of scary novelty python provides which will save you tons of time and headache in the future.
It's a little amusing to see "novelty" paired with "Python," given that the language is 16 years old...
I was in a similar position not so long ago. I'd got deep enough into C++ to really care about design-by-contract and the problems with badly specified and badly tested code. Coming from that mindset, Python seems like everything is held together with string (pun intended) and you feel certain it will all break in some horrific hard-to-trace way as soon as you do anything non-trivial with it.

The way I got out of it was to practice. I recommend the Python Challenge as a great way to get into python. My solutions to the first few problems were c++ translated to python, but as I went on and as I read other people's more 'pythonic' solutions, I started to learn to trust python and write in a more fitting style.
[size="1"]
Quote:Original post by mrbastard
Python seems like everything is held together with string (pun intended) and you feel certain it will all break in some horrific hard-to-trace way as soon as you do anything non-trivial with it.

Yup, that just about sums up my opinion of Python. It's a nice language and I use it now and again for small scripts but doing anything big in it (even a small game) scares the crap out of me.

I quite like being able to perform lots of refactoring and never have to even run the code to be certain that they've been performed correctly - I can do them so that the compiler picks up any mistakes. Likewise I don't enjoy having to wait until a particular line of code has been executed to tell me that I got the order of parameters the wrong way around. (Or worse, ages ago a method was called where the arguments were the wrong way around, and now a rouge object has entered one of my collections and explodes in weird ways sometime much later).
Quote:Original post by Oluseyi
It's a little amusing to see "novelty" paired with "Python," given that the language is 16 years old...


Indeed, I'd meant novel in regards to relative experience not historical absolutes. In the same way functional languages are novel to people who've only ever used c++/java and their kin despite being not being invented recently.
The major reason I find python so enchanting is that it can be used interactively. I know, this sounds like "woo I can execute baby-code a line at a time!", but it's a really powerful feature.

For example, I wrote a complete parser for halflife smd files in a few hours in python. Most of the time was spent in interactive sessions figuring out how to parse the different line types into usable structures, the rest in OOPing the functions I'd written together into a decent API.

It would have taken longer in C++, mainly because the edit-compile-test cycle. Hacking at the data in an interactive session makes it into a puzzle that gives you quick feedback and is fun to work on. The saying "python is executable pseudocode" rings true here - in a typical C++ cycle the 'puzzle' part would have been on paper or as pseudocode. In python the pseudocode you wrote in the 'puzzle' phase can be tested and refactored into your final code.

I'm not sure if I'm communicating this well enough, so I really do suggest having a go at the Python Challenge. Starting with a clue and some data and hacking interactively from there is wonderfully liberating way to code.
[size="1"]
Quote:Original post by mrbastard
The major reason I find python so enchanting is that it can be used interactively. I know, this sounds like "woo I can execute baby-code a line at a time!", but it's a really powerful feature.

But I can already do that anyway with Java (either in Eclipse or via Beanshell) and that doesn't require me to give up compile-time type checking.

Just because C++ is bad at the feedback loop, or allows you to coerce between types and do Naughty Things with memory doesn't mean that python is the only alternative.
Quote:Original post by OrangyTang
I quite like being able to perform lots of refactoring and never have to even run the code to be certain that they've been performed correctly - I can do them so that the compiler picks up any mistakes.

The compiler doesn't pick up all mistakes, and it sometimes introduces new ones. The mindset that "if it compiles, it's correct" is an exceedingly dangerous one... I know that's not what you espouse, but it certainly sounds that way.

Quote:Likewise I don't enjoy having to wait until a particular line of code has been executed to tell me that I got the order of parameters the wrong way around.

Ever heard of unit testing?

Quote:(Or worse, ages ago a method was called where the arguments were the wrong way around, and now a rouge object has entered one of my collections and explodes in weird ways sometime much later).

I don't know what kind of naive code you write where your parameters are so perfectly interchangeable that it takes "ages" for you to detect erroneous invocation. Validate your inputs, please! (And, I might note, static type checking does not equal validation; I can pass the wrong value of the right type in C++ or Java.)

This topic is closed to new replies.

Advertisement