IronPython is easy to learn yet surprisingly powerful language for .NET development. In this article, I’ll introduce you to IronPython and demonstrate it differs from C# and Visual Basic while still allowing you to leverage your existing .NET knowledge.
A Little History
Back before version 1.0 of the CLR shipped, Microsoft engaged a variety of commercial and academic organizations to produce languages that ran on .NET, an effort that was code-named “Project 7”. One of those languages was Python for .NET, which was developed by ActiveState. While ActiveState’s Python for .NET implementation worked, they found “[t]he speed of the current system is so low as to render the current implementation useless for anything beyond demonstration purposes.”1 Furthermore, while they blamed some of the performance problems on “the simple implementation of the Python for .NET compiler”, they also claimed that “[s]ome of the blame for this slow performance lies in the domain of .NET internals and Reflection::Emit”.
Largely due to ActiveState’s experience, it became conventional wisdom that “[t]he CLI is, by design, not friendly to dynamic languages.”2 This caught the eye of Jim Huginin, the original creator of Jython-an implementation of Python for the Java VM. Given that Jython runs reasonably well on the JVM, Jim wondered why CLR ran Python so badly. He decided to take a couple of weeks and build a simple implementation of Python on .NET in order to determine what Microsoft had done wrong and write a short paper titled “Why .NET is a Terrible Platform for Dynamic Languages”.
Jim was shocked to discover that his two-weeks of effort resulted in a Python implementation that ran faster than Jython. He kept working on IronPython, eventually joining Microsoft in the summer of 2004. The 1.0 version of IronPython shipped two years later, in September 2006. Today, Jim is an architect in the Dynamic Language Runtime team while the IronPython team is driving towards a fall 2008 release of IronPython v2.0.
The IronPython project lives on CodePlex at http://www.codeplex.com/ironpython. Unlike most other Microsoft language products, IronPython runs as a transparent, open source project. The IronPython team releases a new version approximately every six weeks. Furthermore, Microsoft makes all the source code available under the OSI approved Microsoft Public License. On the CoDePlex site you’ll find a mailing list for community discussion as well as a public issue tracker where anyone can submit bugs they find.
The current released version of IronPython is v1.1.1, however, the IronPython team is hard at work on v2.0. As I write this, we have just released Beta 3 of IronPython v2.0. IronPython v2.0 implements the 2.5 version of the Python language (IronPython v1.x implemented Python v2.4). Furthermore, IronPython v2.0 is built on the new Dynamic Language Runtime, which I’ll discuss further later in the article.
Regardless of which release you download, IronPython releases are distributed as a simple zip file with the compiled binaries, as well as some tutorials, documentation, and the usual readmes and license files. You can simply unzip that archive wherever you want to on your hard drive. Inside the unzipped files you’ll find the main IronPython executable, ipy.exe. If you run that with no arguments, you get an interactive console window where you can start typing Python code directly. Alternatively, you can pass the name of a python file as the first argument, and IronPython will execute that code.
Currently, there isn’t a production quality development experience for IronPython in Visual Studio. The VS Extensibility SDK includes a sample IronPython language service, project system and console window. This sample has been packaged up as IronPython Studio and is available as a free download from CodePlex (http:// www.codeplex.com/IronPythonStudio). Improving the Visual Studio experience for the IronPython developer is one of the areas of investment for the IronPython development team going forward.
Probably the most notable difference when you first start working with Python is the use of significant whitespace. In C#, whitespace is entirely insignificant - statements end with a semicolon and scope blocks are delineated with curly braces. VB, on the other hand, uses the end of line to indicate the end of a statement. However, scope blocks are still explicitly terminated in VB, typically with the word “End” (i.e. End Sub, End Function, End Class) though sometimes with a word more relevant to the block being closed (Do/Loop, For/Next, etc).
In contrast, Python uses significant whitespace both for statement termination as well as delineating scope blocks. Like VB, statements are terminated by the end of the line. The start of a scope block is explicitly marked with a colon in Python, similar to how C# uses the open curly brace. However, unlike VB or C#, Python uses indentation to implicitly determine the end of a code block. All code with the same level of indentation is part of the same code block. To demonstrate, here’s an implementation of the bubble sort algorithm written in Python:def bubble_sort(ar):
l = len(ar) - 1
for i in range(l):
for j in range(l-i):
if ar[j] > ar[j+1]:
temp = ar[j]
ar[j] = ar[j+1]
ar[j+1] = temp
This code has four scope blocks: the bubble_sort function itself, the two for loops (Python’s for loop is the equivalent of C#’s foreach loop and the range function is the equivalent of Enumerable.Range), and the if block. Each of those blocks is at a different level of indentation. You can see that the return statement is at the same level of indentation that the first for loop is at, indicating that it’s not part of either the for or if scope blocks, but it is a part of the function scope block. In this example, I’m using four spaces for indentation, but the specific amount of indentation is irrelevant, as long as it’s consistent.
Significant whitespace enables both consistency and readability. In C-syntax languages like C#, everyone has their own opinion as to where braces go, tabs vs. spaces, when to indent and how much, etc. Since C# doesn’t care about whitespace, there are numerous ways to format your code-but a given person typically has their single preference. In Python, there’s only one legal way to format the code. This means that if you walk up to a random bit of Python code written by some person you’ve never met, it’ll be formatted exactly in the same style the Python code you write is. This typically makes Python code more readable. Furthermore, readability is also improved because you don’t need extraneous syntax (semi colons and curly braces) to indicate the ends of statements and scope blocks.
Python’s significant whitespace is one of those things developers tend to either love or hate. However, the use of significant whitespace does appear to becoming more popular. Both Boo and Cobra, two open source .NET languages, use a Python-inspired syntax, including significant whitespace. Furthermore, Microsoft’s new F# language includes an optional lightweight syntax mode that makes indentation significant, just like Python.
While significant whitespace is the most obvious difference between Python and C#/VB, the biggest difference between them lies in the type system. Python shares many high-level concepts with these .NET languages, such as imperative code, functions, classes and objects. However, C# and VB are statically typed, which means that the capabilities of individual types are fixed at compile time. Once you decide on the fields, properties and methods of your type and you run the compiler, those capabilities can never change, ever. If you need to change them, your only option is to throw away your original compiled binary and recompile a new one.
Dynamic typing, on the other hand, does not fix type capabilities at compile time. Rather, types become completely mutable and can be manipulated at run time in much the same way that type instances are. Creating new types, adding fields or methods to a type, removing fields or methods from a type, adding fields or methods to a specific instance of a type, even changing the inheritance hierarchy of a type are all allowed at run-time in Python.
If you come from a static type language background, the idea of being able to manipulate types at run-time may seem strange, or even dangerous. Static advocates typically highlight type safety as one of the primary benefits of using static typing. When all the capabilities of a type are fixed at compile time, the compiler can do quite a bit of validation to ensure that types you create and methods you call all exist, fields and parameters are of the right types, etc. We’ve all had to fix compiler errors because we misspelled a method or type name. In Python, those compiler errors become run-time exceptions.
However, I’d like to put this type safety benefit in perspective. In any system of significant scale, there are essentially an infinite number of ways the application can be wrong. Type safe languages eliminate one of this infinite number of ways. The overwhelming majority of errors and bugs you might make when developing your system won’t be caught by a static type language compiler. If they could, then any application that compiled would automatically be bug free! You need some other mechanism to catch these other errors, typically automated unit tests. So while it’s true that static types do provide a safety net, it’s just not a very big one.
This isn’t to say type safe languages are bad. Rather, I look at it as a tradeoff of static type safety vs. dynamic type flexibility. There is no universally right decision-only the right decision for you and your project. The good news is that with the addition of dynamic languages like IronPython to Microsoft’s language stable, you can make that tradeoff decision while still staying in the .NET realm.
By: Harry Pierson
Harry Pierson is the IronPython Program Manager. A ten year Microsoft veteran, Harry has also spent a significant amount of his career focused on architecture and services. He writes a blog on technology, programming, architecture and occasionally ice hockey at http://devhawk.net.
IronPython started as an effort to find out why .NET was bad for dynamic languages.