IPy Post 2.0 Roadmap Clarifications

Two weeks ago, I posted a roadmap for where IPy is heading after we get 2.0 out the door later this year. I got two questions in the comments that I wanted to address.

  • Michael Foord wants to know “will you actively maintain IronPython 2 and IronPython 3 in parallel?”
  • francois wants to know for the VS integration “Will it be necessary to buy VS standard/Pro to benefit from it?”

As to the first question, Curt Hagenlocher (aka Iron Curt) from the IPy dev team wrote the following on the IPy mailing list:

“I think it’s fair to say that this will be driven mostly by the needs of our community and of the larger Python community. By the time IronPython 3.0 ships, it’s likely that CPython 3.0 will have been out for a year or even longer, and we’ll have a much better idea of what the uptake is like in the community.”

Let me second Curt’s comment. I used to think getting to 3.0 as quickly as possible was one of our highest priorities. However, it looks like the CPy 3.0 uptake rate is a real open question right now. If the Python community takes 3-4 years to fully embrace 3.0 (as Michael suggested) then I don’t see how we will have any choice but to maintain both in parallel. It also suggests that better 2.6 support may be more important than 3.0 support, at least for the next 18-24 months.

Francois’s question is much easier: No, we will not require you to buy any version of VS in order to get IPy VS integration. It will work with the Visual Studio Shell, much like the current IronPythonStudio VSX sample does today.

For out first release, we are focusing on the integrated mode scenario. This means that if you own a copy of VS (other than express), the IPy tools will snap into your existing VS installation. If you don’t own a copy of VS, you’ll be able to download and install the integrated shell for free and our IPy tools will snap into that. Down the road, we might investigate an “IronPython Express” version that leverages the isolated shell, but that’s not a priority right now.

The VS shell includes support for the WinForms and WPF designers and we expect to support both eventually. WPF support is fairly straightforward since the designer works with XAML files rather than code files. WinForms support is harder, since it wants to emit statically typed code into code files – a neat trick for a dynamically typed language like Python. The current implementation that the IronPythonStudio sample uses requires us to inject a bunch of custom type hints disguised as python @decorators in order to round trip between the designer and code views. However, we’re not bringing those custom type hints forward in the 2.0 release so we’ll need to find a better way to integrate with the WinForms designer.

As for web apps, ASP.NET support is currently on the back burner while Jimmy and David drink coffee and expensive juice while they figure out the ASP.NET / dynamic language story. We also want to support Silverlight development for IronPython in VS, but I’m exactly sure how we get Silverlight designer support yet. Silverlight Tools for VS08 today require VS Standard, so I’m guessing there’s some leg work to do if we want to support the SL designer in VS Shell.

As always, feel free to ask here or on the mailing list if you’ve got any questions or feedback on our plans.

Monadic Philosophy Part 2 – The LINQ Monad

If you don’t come from a math or philosophy background (and I don’t) “monad” sounds like a made-up word. Of course, understanding OO’s use of terms like “class” and “object” can be hard to grok at first too. But at least those terms have some grounding in real-world concepts that non-math geeks come across. Because I couldn’t draw an analogy of monads to anything at first, it made grasping the concept of monads very hard for me.

It’s such a unfamiliar word that the F# team doesn’t like it either:

“[W]hen the designers of F# talked with the designers of Haskell about this, they agreed that the word monad is a bit obscure and sounds a little daunting and that using other names might be wise.”
[F# Workflows and Haskell Monads, Expert F#, p232]

The F# team thought about calling them workflows, but settled on computation expression. Frankly, I don’t like these names much better. Workflow is too easily confused with WF and if the term computation expression is way to generic. Isn’t everything in programming a computation expression? I think I’ll just stick with monad.

Of course, if there was a short, pithy way of describing a monad, I’m sure that’s what we’d call them. It’s a kinda complicated idea, so there’s no simple two or three word phrase that accurately describes it. “Sequential computation with context flow” is the best I could come up with. It’s a crappy description, but here’s an elegant example that most .NET programmers are probably already familiar with.

var Orders = new List<Order>()

//code to populate orders omitted

var q = Orders
    .Where(x => x.OrderDate < DateTime.Now)
    .OrderBy(x => x.OrderDate)
    .Select(x => new {ID = x.OrderID, Date = x.OrderDate})

Yes it’s true: LINQ is a monad. The two basic concepts about a monad from my description above is that it’s a) a sequence of operations and b) there’s a context that flows from operation to operation. We see both here in this simple LINQ query. I realize I’m using what looks like a LINQ to SQL query here, but for the sake of argument let’s assume that this is all happening in memory.

The query is a sequence of three operations: Where, OrderBy and Select. LINQ has a set of standard query operators that you can mix and match in whatever order you need to. Part of the monad’s job is to enforce the sequence of actions. For C#, that’s not really a big deal, since it has explicit sequencing already. However, other languages like Haskell use lazy evaluation, meaning there is no explicit order of execution. Many lazy evaluation languages use monads in areas, such as I/O, where order of execution matters.

While C# doesn’t need any help to enforce execution order, monads are very useful in the way they flow context between the operations. In the case of LINQ, all the standard query operators take an IEnumerable<T> as their first parameter and return an IEnumerable<T>. Since they have the same inputs and outputs, they can be plugged together in whatever order is required. Yet, you don’t see any reference to GetEnumerator or the enumerator objects they return in the LINQ code above. All that code is hidden inside the LINQ query operators so the LINQ developer doesn’t have to look at it.

If you squint hard enough, IEnumerable kinda looks like a functional construct. It exposes a single method (GetEnumerator) and can be passed around much the same way functional languages like F# pass around first-order functions. Furthermore, the result of calling GetEnumerator is an IEnumerator object that likewise exposes one main function (MoveNext). In other words, you can think of IEnumerable sort of like a function that returns a function that you call to iterate the collection.

So to sum up, a monad is a sequence of operations in a specific order that automatically flows context from one operation to the next. In the LINQ example, C# has built-in constructs – IEnumerable<T>, foreach and yield return – that makes the monad seem less foreign (which is why I used it as my first example!) However, as we’ll see, the concepts of sequence and context flow in a monad still hold even if we’re not using built in features of C# to implement them.

Monadic Philosophy

(Since I accidentally published part one of this series a few minutes ago, I figured I might as well start publishing the series.)

If you start learning functional programming, eventually you’ll come across the idea of a monad. Coming from the object/imperative world of languages like C#, I’ve had a hard time wrapping my head around this concept. There’s no shortage of monad tutorials out there, but most use Haskell’s IO as the prototypical example of a monad. Given that I don’t know Haskell very well, I found it hard to separate the Haskell stuff from monad stuff. So I set monads on the back burner and decided not to worry about them.

However, all that changed when Stephan Tolksdorf alerted me to his very cool monadic parser combinator library FParsec. I found the FParsec parsers much easier to read my F# parser efforts, so I became very interested in monadic parser combinators. As you might guess, a “monadic parser combinator library” makes heavy use of monads. Time to switch burners.

The problem with learning monads with FParsec is that it’s really designed for production use. I needed to break monads down to first principles, so I rolled my own monadic parser library. Make no mistake, if I were looking to build a production parser in F# right now, I’d use with FParsec. My monadic parser library might “get there” eventually, but right now it’s a toy.

Over a series of posts, I’m going to describe what I know about monads. I didn’t set out to write a tutorial on monads – as I said, there are plenty of them out there. However, I found most of the the many monad tutorials I read lacking because the did a good job explaining the “how”, but not such a good job on the “why”. Coming from an imperative world, I wanted to understand the philosophy better. That being said, there’s a lot of tutorial in and around the philosophy. Hopefully, you’ll find both useful.

Pushed the Wrong Button

I’m working on a new series of posts on parser monads, but I accidentally pushed out part thre (I hit “Publish” instead of “New” in WL Writer). I can’t stop you from reading it, as it’s already in Google and FeedBurner’s cache. However, if you want any context at all, do yourself a favor and wait until I publish parts one and two first!

Some Powershell Scripts

By popular demand, I uploaded a bunch of my scripts to my SkyDrive. Included are:

  • Set Powershell Home – this is actually a zip file that contains the profile redirect script. Unzip this in your Documents folder and change the path in Microsoft.PowerShell_profile to where ever you want your profile and home directories to live.
  • _profile – my “real” profile script. Note, the su function requires the Script Elevation PowerToys in order to work. Also, all the various aliases are hard coded to their location on my machine. You’ll probably want to change them.
  • prompt – my prompt script
  • prepend-path – a script to add a directory to start of my path
  • append-path – like above, but adds the directory to the end of the path
  • append-path-perm – like append-path, but permanently updates the path in the registry

Enjoy.