How learning Python changed my life
Part I
This is not yet another rant about some developer’s affinity for Python. It is rather an accurate account of the impact of learning one of today’s trending programming languages, i.e. Python, on my skills and capabilities.
I got to learn Python out of genuine curiosity shortly after I started my first job at one of Microsoft’s first R&D labs in Egypt (late 2006). I used to write lots of C# code snippets to help me automate several data/text processing tasks. Back at that time, I could only write C++ and C#.
My initial impression was very positive. I liked the clean syntax and got intrigued by the boldness and creativity behind using indentation to define code blocks. On the syntactic level, I liked keyword arguments, list comprehension and all the various ways you could index into sequences. Moreover, I was especially fascinated by all the standard libraries Python ships with (which Python enthusiasts like to express as “batteries included”).
I started using Python for my day to day scripting and automation tasks and I must say it felt a lot more appropriate and convenient for such tasks. And although PythonWin did not come across as the most impressive or capable IDE I have ever used, it was very usable and lightweight. It felt broken but in a very usable way if I could say s0. It also featured a very easy-to-use debugger and, in general, was perfectly adequate for everyday scripting.
Functional programming
I was keen on learning more about Python. So, I started looking around for books and materials. It wasn't long before I came across David Mertz’ excellent “Text Processing in Python” among a couple of other books. Text processing was definitely something I did day-to-day and I was wondering what was out there to make it easier.
One of the earliest parts of the book tackled the issue of utilizing “Higher-Order functions” in text processing. I did not really know what Higher-Order functions were at that time nor was I acquainted with Functional Programming in first place. I followed the book closely and got mixed feelings about the concept in the end. On one hand, I was quite impressed by the terseness and succinctness of the code presented in the book. For instance, I really liked being able to compose new functions by combining other functions together as follows:
>>> def add(a, b):
... return a + b
...
>>> def double(a):
... return 2 * a
...
>>> add_then_double = compose(double, add) # add_then_double(x, y) = double(add(x, y))
>>> add_then_double(10, 20)
60
What we did here was simply taking 2 functions add() and double(), and compose a new function add_then_double() that simply does double(add(a, b)) without having to change the implementation of either function.
On the other hand, I was somewhat puzzled when I attempted to understand how compose() actually did that.
But the usefulness of the concept was so evident I could not ignore it. I mean, think of all the possibilities that this could enable.
- Think of composing functions that do authentication with any other functions of interest to have these functions do authentication before they execute so that they are only executed if they are invoked by authenticated users. (Aspect-oriented programming fans will relate. Boy, wait until they learn about Python decorators.)
- Think of composing a function that takes long to execute — e.g. one that takes a URL as input, crawls its contents and returns it as a result— with another that does caching to get a new function that would not crawl any given URL twice as it caches previously crawled URLs.
- Think of composing any function of interest with another that adds timeout capability to that function.
- Think of composing any function of interest with another that simply makes it asynchronous.
The possibilities are endless. In fact, there are countless innovations the Python community has built utilizing the concept of Higher Order functions, i.e. functions that receive functions as input and return other functions — mostly modified to do something useful. (In fact, almost all the ideas above are already implemented in Python Decorator Library)
Although David Merz’ “Text Processing in Python” was published more than 10 years ago, I think it is still an incredible source of knowledge about Python in general and about advanced and serious text processing methods that are not specific to Python in essence. The book is available in a very readable text format free of charge on the author’s website.
The introduction to Higher-Order functions occurs in the very first chapter of the book titled “Python basics”. Appendix A of the book also gives a fairly preliminary yet pragmatic introduction to Functional Programming.
To be able to understand some of the details in that chapter, you may find it useful to take a look at a brief explanation of Python’s built-in map(), filter(), reduce(), zip() and lambda, most of which are explained pretty simply right here.
Functional Programming is a very interesting paradigm, and what you’ll learn in this first chapter is one direct and useful application of that concept. However, this is not to say that Python is essentially a Functional — or even functional-first — Programming language, although it does definitely support the paradigm to some extent. However, this is to say that playing around with Python as in the examples of the first chapter of David Merz’ “Text Processing in Python” showcases some very handy uses of the paradigm and enables us to play with them in a an easy and approachable manner.
That was one of the most profound effects learning Python has had on my technical perception. It was such a nice introduction that paved the way for my later endeavors with Lisp and Haskell. But that’s a story for another day.
Email me when hamid publishes or recommends stories