Passion * Technology * Ruthless Competence

Thursday, July 31, 2008

Monadic Philosophy Part 3 - The Parser Monad in C#

(If you disregarded my advice and read the previous version of this post, please note I rewrote this post significantly so you'll probably want to read it again.)

In the last post, we looked at how LINQ is a monad and how IEnumerable is a pseudo-functional construct. However, C#'s intrinsic collection support - aka foreach and yield return - really obscure how you might go about building your own monad. So for this post, we're going to take a look at a parsing monad instead. Just as LINQ broke the big problem of queries into a collection of standard query operators that were composable, we want to take the same approach for parsers.

Note, I'm going to stick with C# for now, and get into F# monads in my next post. Quick shout out to Luke Hoban and Brian McNamara, from whom I stole obtained some of the code below.

Quick refresher: I've described a monad as a sequence of computations with a context flow. Since C# has explicit sequencing, we want to focus on the context flow. For LINQ, the context was IEnumerable. For parsers, we could define an similar IParser interface like this:

class Tuple<T1, T2>
{
    public readonly T1 Item1;
    public readonly T2 Item2;
    public Tuple(T1 val1, T2 val2) { Item1 = val1; Item2 = val2; }
}

class Result<T> : Tuple<T, string>
{
    public Result(T val, string rest) : base(val, rest) { }
}

interface IParser<T>
{
    Result<T> Parse(string input);
}

The Parse function takes a string to be parsed as input and returns the parsing result which pairs the semantic value with with the remaining string input to be parsed. I've built out a simple generic tuple class because I know I'll use it again later. I've long wished C# would support intrinsic tuples like F# does. For convenience, I've also created a strongly typed subclass of Tuple to represent parse results where the second item is a string, to save some typing. Since Result is a class, it can be null which means the the Parser failed to parse the input.

The problem with this approach is that unlike IEnumerable, the C# compiler has no built-in knowledge of this interface. That means there are no easy-to-use keywords like foreach and yield return that can do our heavy lifting of consuming or creating these IParser types for us. Instead, we would have to explicitly declare classes to implement the interface. As we add more and more parsers, that additional overhead of creating types would become more and more unwieldy. Instead, let's redefine Parser as a delegate.

delegate Result<T> Parser<T>(string input);

The benefit of this approach is that you can create Parser delegates inside functions, using C#'s anonymous delegate syntax, without the overhead of creating a type. For example, here's a function to create a simple primitive parser that strips the first character off the parse string and returns it as the parse result:

static Parser<char> Item()
{
    return input =>
        {
            return string.IsNullOrEmpty(input)
                ? null
                : new Result<char>(input[0], input.Substring(1));
        };
}

That's a lot more convenient than building a type just to implement a single method.

Now that we have our Parser type, we need to think about how to compose Parsers so that we can flow context between them. Much as LINQ provides a collection of primitive query operators (Select, Where, OrderBy, etc), you would expect a monadic parser library to provide a collection of primitive parsers (Item, Satisfy, AnyOf, ItemEqual, etc), that you could combine into higher-order parsers along with some language specific lower-order parsers. Here's an example from the the PEG grammar:

    Primary <- Identifier !LEFTARROW / OPEN Expression CLOSE / Literal / Class / DOT

The Primary parser depends on some high-order language specific parsers (Identifier, Expression, Literal and Class) as well as some language specific low-order tokenizer style parsers (LEFTARROW, OPEN, CLOSE and DOT) and finally some language-independent primitive parsers (the failure predicate ! and the prioritized choice operator /).

So how should we compose these various Parsers? LINQ query operators were fairly easy to compose because they all take in and return the same type (IEnumerable) so you can simply chain them together. Parsers are a little trickier because the inputs and outputs are asymmetric - i.e. they take a string, but return a Result - so simple chaining won't work.

We could combine the parsers sequentially, taking the parse string returned from first parser and feed it into the second. Then we could combine the two parse values in a Tuple to return them (you see why I created a generic Tuple class?) resulting in a function that looks like this:

static Parser<Tuple<T1,T2>> Join<T1,T2>(this Parser<T1> p1, Parser<T2> p2) 

    return input => 
        { 
            var ret1 = p1(input); 
            if (ret1 == null
                return null

            var ret2 = p2(ret1.Item2); 
            if (ret2 == null
                return null

            return new Result<Tuple<T1,T2>>( 
                new Tuple<T1, T2>(ret1.Item1, ret2.Item1), 
                ret2.Item2); 
        }; 
}

Note this is an extension method so we can call Parser1.Join(Parser2) rather than the less fluent Join(Parser1, Parser2). I was going to call this function Combine, but there's already a static Combine method on the Delegate type that caused a conflict, so I used Join instead.

The Join approach works, but it's a bit unwieldy to return the parsing values in a tuple. Every set of joined parsers will result in another level of tuple nesting in the Result that's returned. That gets pretty ugly pretty fast. For example, lets say we want to create a parser that combines two instances of Item. It looks like this:

static Parser<Tuple<char, char>> TwoItems()
{
    return Item().Plus(Item());
}

That's not so bad. But now look what happens if we combine the TwoItems parser with another instance of Item:

static Parser<Tuple<Tuple<char, char>, char>> ThreeItems()
{
    return TwoItems().Plus(Item());
}

The result is a nested tuple. Yuck. We need a better way. Enter the monadic bind. The code looks like this:

static Parser<U> Bind<T, U>(this Parser<T> p1, Func<T, Parser<U>> fun)
{
    return input =>
        {
            var ret1 = p1(input);
            if (ret1 == null)
                return null;

            var p2 = fun(ret1.Item1);
            if (p2 == null)
                return null;

            return p2(ret1.Item2);
        };
}

Like the Join function above, Bind starts by calling the first parser function, returning null if the parse fails. However, instead of calling to the second parser directly, it calls to the provided function that generates the second parser. This function acts as a closure, packaging up the parse value from the first parser for later processing. Finally, Bind calls to the generated second parser, feeding in the remaining text from the first parser result.

This approach allows you to inject code that combines the parsing values however we like rather than always pairing them up in a tuple. Here's a version of TwoItems that binds a call to Item with a custom function that calls Item again and returns the two characters as a string rather than a tuple:

static Parser<string> BetterTwoItems()
{
    return Item().Bind<char, string>(
        val => 
        {
            return input =>
            {
                var result = Item()(input);
                return new Result<string>(
                    string.Format("{0}{1}", val, result.Item1),
                    result.Item2);
            };
        });
}

It's kinda strange to see a lambda expression that returns a lambda expression in C#, but that's what this code does. The first lambda expression (val =>) defines the custom function, the second lambda expression (input =>) defines the Parser delegate. Val is the parse value from calling Item() the first time - ret1.Item1 in the Bind function above. Input is the remainder of the parse string - ret1.Item2 from the Bind function.

Unfortunately, while this approach avoids nested tuples for parse values, we've had to give up quite a bit of simplicity. The original TwoItems method was a single line of code. BetterTwoItems is significantly more complex. Furthermore, the double lambda expression syntax confuses C#'s type inference, forcing you to explicitly specify the generic types on the Bind method. Luckily there's a better way to write this. However, let's start by rewriting the function like this:

static Parser<string> SlightlyBetterTwoItems()
{
    return Item().Bind(
        v1 => Item().Bind<char, string>(
            v2 =>
            {
                return input =>
                {
                    return new Result<string>(
                        string.Format("{0}{1}", v1, v2),
                        input);
                };
            }));
}

SlightlyBetterTwoItems pulls the second call to Item out into a second Bind operation. The point of this refactoring is to make it clear that we can view this function as a call to Item, bound to a second call to Item, bound to custom function to return a Parser that returns the two parse value chars formatted as a string. You'll notice that by eliminating the the double lambda expression on the first call to Bind, we were able to drop out the explicit generic type specification.

This version is a little clearer, but we can make it clearer yet. It turns out that wrapping up a parse value in a Parser that unconditionally returns the parse value and the parse text input in a Result is a very common operation. So let's create a primitive function Result to wrap up a parse value in a Parser delegate and build our final version of TwoItems that uses it.

static Parser<T> Result<T>(T val) 

    return input => new Result<T>(val, input); 


static Parser<string> BestTwoItems()
{
    return Item().Bind(
        v1 => Item().Bind(
        v2 => Result(string.Format("{0}{1}", v1, v2))));
}

Now it's very clear that we have a call to Item, bound to a second call to item, which is in turn bound to a call to Result. We've now dropped all use of double lambdas, which means C# can infer the types to each of our Bind calls implicitly. But more importantly, do you see any reference to Parser<T> delegates or input strings in this code? Only in the return type specification. Just as LINQ hides the specifics of flowing IEnumerable or enumerator objects between standard query operators, the parser monad hides the specifics of flowing Parser delegates or input strings between parse operations.

The Parser delegate plus the Bind and Result methods are all there are to our basic parser monad. Seriously, all that worry that monad "is a bit obscure and sounds a little daunting" and it's really just two functions and a delegate type.

While this code is fairly straight forward, the whole nested lambdas expressions is fairly atypical syntax that some developers might have a hard time understanding. Unfortunately, if we're writing our parsers in C#, we're kinda stuck with this syntax. However, F# has a special syntax that lets you write what looks like normal sequential code, while still flowing the Parser context between parse operations exactly like the code above does. We'll take a look at that syntax in the next post.

Posted By Harry Pierson at 8:47 PM Pacific Daylight Time

Wednesday, July 30, 2008

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.

Posted By Harry Pierson at 3:43 PM Pacific Daylight Time

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.

Posted By Harry Pierson at 9:53 AM Pacific Daylight Time

Tuesday, July 29, 2008

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.

Posted By Harry Pierson at 5:10 PM Pacific Daylight Time

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!

Posted By Harry Pierson at 5:06 PM Pacific Daylight Time

Monday, July 28, 2008

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.

Posted By Harry Pierson at 4:26 PM Pacific Daylight Time

DevHawk's Slightly Useful Powershell Configuration

Since folks were interested in my favorite tools, I thought I'd blog how I have PowerShell configured. I'm not an ultra-power user, but I hold my own and hopefully you can use some of this configuration for yourself. Please tell me you're not still using CMD.

First, I use a trick I picked up from Tomas Restrepo to change your home directory and profile script. Here's my Microsoft.PowerShell_profile.ps1 file (in the WindowsPowerShell subdirectory of My Documents)

# reset $HOME and $PROFILE variables
set-variable -name HOME -value "D:\HPierson.Files" -force 
(get-psprovider FileSystem).Home = $HOME 
set-variable -name Profile -Value "$Home\Scripts\_profile.ps1"

# Run the $PROFILE script
. $profile

By default, PS uses the user's personal directory (c:\users\hpierson in my case) as the home directory and the aforementioned filename for the profile script. Personally, I like to keep all "real" data off my boot partition so that I don't have to back it all up when I repave. So my "real" home location is d:\HPierson.Files. The above script sets both the $HOME variable and file system home property to this directory. It also resets the $PROFILE variable to a script in my $home\Scripts folder and runs it.

My $PROFILE script does several things of note:

  • It adds the aforementioned $home\Scripts folder to the path. My utilities folder is a permanent part of the path, put I only add the scripts folder when I'm actually running PS.
  • If I'm running as administrator, I set the background color of the console window to red. I think I picked up this script from Brad Wilson at some point.
  • Set location to home, otherwise when I start PS as admin, it starts in c:\win\sys32.
  • I have a simple prompt script file that displays current folder, the current command number and a list of yellow plus signs indicating how deep I am in the directory stack. To get it to work, I have to remove the standard prompt function, which I do in $PROFILE.
  • I can't ever remember the space between "cd" and "..", so I wrote a simple function called "cd.." that executes "cd ..".
  • I have a su function that leverages the Script Elevation PowerToys. If you pass in a command, it executes it with elevated credentials. If you just execute su, it runs an elevated PowerShell.
  • I use 7-zip for my compression needs, including the 7za command line app. However, PS has issues w/ executing an exe that starts with a number. So I aliased 7za as "zip". UPDATE: Tomas points out that you can prepend an ampersand to force execution, so I could have typed "&7za". I forgot that when I created the alias and am now used to using zip, so I'm not going to change it. But I thought you should know.
  • I have an ever-changing set of aliases, depending on my needs. Currently, I alias "ipy", "cpy", "fsi", "fsc", "devenv" and "chiron" to their fully path-qualified equivalents, so I can run them from anywhere without having to add their respective folders to the path.

I don't set vsvars in the $profile script, but I do have a copy of the one Chris Tavares wrote in my scripts folder, so I can set up a VS environment in a moments' notice.

Also, I put PowerShell on the Vista quick launch bar, so I can bring it up by typing Win-2.

Posted By Harry Pierson at 9:52 AM Pacific Daylight Time

Friday, July 25, 2008

Morning Coffee 171

  • Big news for IronRuby out of OSCON. John and Jim have the details. Congrats to the IronRuby folks on reaching these milestones and paving the way for others (i.e. IPy) to follow some of the same paths.
  • One of those OSCON announcements, is a project my teammate Jimmy Schementi has been working on: Silverline, which "let's you write Rails code that can run on the client".
  • Shri Borde - the dev manager for IPy, IRuby and F# - tackles a tricky subject of static compilation of dynamic Python code. This came up on the mailing list recently as one of the outstanding requests for IPy to do is support custom attributes, which requires static compilation. Shri lays out some of the big issues with this approach. However, the community has been fairly clear on this, so it's obviously something we need to look at.
  • I met someone from MS Research at the MS Product Fair who pointed me to the Institute for Personal Robots in Education, a joint effort between Georgia Tech and Bryn Mawr College and sponsored by Microsoft Research. Their Myro software (myro == my robot) is written in CPython, but there's an effort underway (aka Miro 3.0) to build a .NET version that uses IronPython. Must investigate.
  • Seshadri shows how easy it is to extend C# types in IronPython. It's also shows how simple it is to host DLR code in your app - it's like 6 lines of code!
  • Early reviews of IronPython in Action are good.  
  • If you want to run an IronPython IDE in your browser with Silverlight, check out SilverShell from Dan Eloff.
  • The XNA team has announced their business plans for community games. Basically, you set a price point between 200 and 800 points (aka between $2.50 and $10) and receive a "baseline" of 70% of the revenue the game generates. More details are available in the FAQ. This is pretty excited. I'd like to build some co-op kids games.
  • Speaking of XNA, Caligari is now offering TrueSpace 7.6 for free . David Weller and Glenn Wilson provide an XNA viewpoint on the announcement, Chris Pendleton shows how to upload your models to VirtualEarth.
  • Congrats to the CodePlex team on their latest drop, which features that a cool new feature - Mailing Lists! IronPython has had a Mailman mailing list for years, so I'm not sure we'll use this feature on IPy, but I'll investigate it
  • Two PDC notes: First, Rick Rashid - VP of MS Research - will be delivering a PDC keynote. Second, the PDC team has put up a video podcast on Producing a Ginormous Conference in 10 Minutes or Less! It's the "inaugural episode" so watch for more Countdown to PDC video podcast episodes in the future.
  • I recently discovered Chris Smith's F# blog. He's got recent posts on Mastering F# Lists and Guidelines for Readable F# code. For the F# novice, check out his F# in 20 Minutes posts (part one, part two)
  • Pat Helland is moving to the SQL team. Good luck Pat!
  • I like Nick Malik's formal definition of use cases, but I can't help be reminded of Charlie Alfred's Value-Driven Architecture article in Architecture Journal 5 where he said use cases were "easy to teach and explain" but that "if simplicity were the only goal that counted, we'd all still be walking or riding horses to get from one place to another."
Posted By Harry Pierson at 11:41 AM Pacific Daylight Time

Monday, July 21, 2008

Five Minutes Past Noon Coffee 170

  • Ben Hall announces IronEditor, a simple dev tool for IronPython and IronRuby. Pretty nice, though fairly simplistic (as Ben readily admits). For example, it doesn't have an interactive mode, only the ability to execute scripts and direct the output to IronEditor's output window. However, it is a good start and I'm sure it'll just get better. One thing he's apparently considering is a Silverlight version. (via Michael Foord)
  • Speaking of "Iron" tools, Sapphire Steel have had an IronRuby version (in alpha) of their Ruby in Steel product for several months now. I wonder if John's had a chance to play with it.
  • Speaking of John, the ASP.NET MVC / IronRuby prototype he talked about @ TechEd is now available on ASP.NET MVC Preview 4 via Phil Haack.
  • Ted Neward has an article exploring the IronPython VS Integration sample that ships in the VS SDK. As I mentioned the other day, we're starting working on a production quality implementation of VS Integration for IPy.
  • Ophir Kra-Oz (aka Evil Fish) blogs Python for Executives. I like his "Risk, Recruiting, Performance and Maturity" model - four boxes, perfect for keeping an executive's attention! :) Plus Ophir has some nice things to say about IronPython. (via Michael Foord)
  • Ronnie Maor blogs an extension method for PythonEngine to make Eval simpler. I especially like how he uses string format syntax so you can dynamically generate the code to eval. I wonder what this would look like in IPy 2.0 with DLR Hosting API. (via IronPython URLs)
  • Speaking of DLR Hosting, Seshadri has another great DLR hosting post, this time hosting IPy inside of VS08 so you can script VS08 events (document saved, window created, etc) with Python.
  • Justin Etheredge has a bunch of IronRuby posts - Getting IronRuby Up and Running, Running Applications in IronRuby, Learning Ruby via IronRuby and C# Part 1. (via Sam Gentile)
  • Don Syme links to several F# related posts by Ray Vernagus, though he's apparently also experimenting with IronRuby. I'm really interested in his Purely Functional Data Structures port to F#.
  • Speaking of F#, Brian has a teaser screenshot of F# upcoming CTP. However, he chooses the New Item dialog to tease, which looks pretty much like the current new item dialog (the new one does have fewer F# templates). However, if you look in the Solution Explorer, you'll notice a real "References" node. No more #I/#R! Yeah!
  • The interactive graphic in Kevin Kelly's One Machine article is fascinating. It really highlights that the vast vast vast majority of power, storage, CPU cycles and RAM come from personal computers on the edge. Even in bandwidth, where PC's still have the highest share but it looks to be around 1/3rd, the aggregate of all edge devices (PCs, mobile phones, PDAs, etc.) still dominates the data centers.
Posted By Harry Pierson at 12:05 PM Pacific Daylight Time

Thursday, July 17, 2008

Morning Coffee 169

  • Check out the crowd for a the Washington Capitals developmental camp scrimmage last week (My parents are in their somewhere). Standing room only in the practice facility to watch a bunch of kids, most of whom won't ever make it to the NHL, in July. If you think Washington can't be a hockey town, you are sorely mistaken.
  • Speaking of the Caps, they are establishing a "spirit squad"? Is that really necessary? (short answer: no). Peerless' take is hilarious.
  • Seshadri Vijayaraghavan is a tester on the DLR team and he's been writing quite a bit about the DLR hosting API. He's got a series of posts about hosting, invoking and redirecting output from IronPython in a C# application.
  • I haven't seen an official announcement, but mobile access to Live Mesh is available by pointing your phone browser to http://m.mesh.com. It's mostly a web view of the Live Desktop, though there is a feature to upload photos from your phone. However, for some reason that feature doesn't work for me right now. I don't get the "browse" button.
  • ASP.NET MVC Preview 4 is available for download. Phil Haack has a few details that ScottGu didn't cover. Scott Hanselman shows off some AJAX stuff.
  • Speaking of Scott Hanselman, he highlights the return of Terrarium from Bil Simser. Scott mentions that most Terrarium animal implementations were big collections of nested if statements. I wonder if F# pattern matching would be a cleaner approach?
  • Ted Neward obviously never "even tangentially" touched politics, as I think they have far worse flame wars far more often than we have in the software industry. However, certainly the Scala flame war he's commenting on seems fairly counterproductive.
  • Brad Wilson runs into a wall trying to convert a string to an arbitrary Nullable<T>.He doesn't find an answer, but I found reading thru the steps he took to try and find an answer strangely compelling.
  • Jeff Atwood argues that Maybe Normalization isn't Normal. It's mostly a collection of information from other places, including a compilation of high-scale database case studies. But it's a useful collection of info and links, with a little common-sense thrown in for good measure.
  • I have a hard time imagining Pat Helland camping.
Posted By Harry Pierson at 10:52 AM Pacific Daylight Time

Wednesday, July 16, 2008

IronPython Post 2.0 Roadmap

Michael Foord (aka voidspace) twittered that "None of the IronPython team can get it together to blog regularly, except @jschementi of course." While I'm not sure Jimmy is all that prolific either, Michael's certainly right about me. I started this job at the beginning of April, and I've only blogged twenty one times in the three and a half months since. Worse, I've only blogged six times in the past month and a half - and half of those have been since Michael called out my lack o' posting. My wife has blogged like twenty five times in that same time period. I can only plead pressures of a new job plus a two week vacation. I have been twittering a lot.

Michael was twittering in response to Todd Ogasawara's post wondering about our Python 3.0 plans. Since we haven't been particularly transparent (my fault) I thought I'd lay out our near and middle term plans.

First off, we're on the verge of releasing 1.1.2 (the release candidate is available now), a service release in our 1.x branch which contains a bunch of bug fixes we've back ported from our 2.0 work. This is our last planned release in the 1.x branch. For those who don't know, our 1.x branch tracks CPython's 2.4 branch.

Most of our team's focus has been on 2.0 which we're on track to shipping later this year. Our 2.0 corresponds to CPython's 2.5 branch. It's a major release for us because of the addition of the Dynamic Language Runtime. Currently, you can get 2.0 Beta 3, with Beta 4 scheduled for early August (we go about 6 weeks between beta releases). If you want even fresher code than our latest release, you can pull and build the source yourself. We went about two months without pushing source due to some broken scripts, but they're fixed now so we're going to try and push out code much more often than we have in the past.

For the non-Python geeks in the audience, Python is undergoing a major change. Python 3.0 is going to break backwards compatibility with Python 2.x in number of ways. Breaking backwards compatibility always has to be handled carefully, so the Python community is investing quite a bit of effort to make the transition as smooth as possible.The Python Software Foundation is currently working on both 2.6 and 3.0 simultaneously. The idea is to have as much feature parity between the two releases (except for the stuff being removed from 3.0) and to provide an automatic tool to translating to the new version.

Let me be very clear (since as Todd discovered, we haven't been to date) that once we get IronPython 2.0 out the door, we will start working towards IronPython 3.0, which will be our version of Python 3.0. We want to take the same stepping-stone approach that CPython is taking. So that means at a minimum we'll do an IPy 2.1 with CPython 2.6's new language and library features, (along with the usual bug fixing and other quality improvements we do every cycle) before then proceeding to work on IPy 3.0.

Until we get IPy 2.0 out the door, I'm not willing to talk about specific timelines. We're an agile project and we're going to be feature and quality driven, full stop. There were about seven months between the release of IPy 1.0 and 1.1, however that didn't include much new Python feature work so it's not a good comparison IMO. My gut tells me the IPy 2.1 release will take longer than a typical minor release while the IPy 3.0 release won't take as long as a typical major release. Note, those are guesses, not commitments.

Besides IPy 2.1 and 3.0, the other major thing we're working on is Visual Studio integration for IronPython. Yes, there is IronPythonStudio, but that's a VS SDK sample not a production-quality VS integration the IPy team maintains or supports. The IntelliSense implementation is pretty flaky, the compile-oriented project system feels pretty un-pythonic and of course we need to upgrade it to support IPy 2.0 and the DLR (it would be nice if IronRuby could leverage our efforts down the road). Like everything else we do in this group, we'll be publishing the VS Integration source code up on CodePlex as early and often as we can.

So to recap our current thinking:

  • IPy 1.1.2 in RC now, shipping in several weeks assuming we don't find any major regressions
  • IPy 2.0 in beta now, shipping later this year
  • IPy 2.1 supporting new CPy 2.6 features at some point after IPy 2.1, probably longer than a typical minor release
  • First release of IPy integration with VS in the same timeframe as IPy 2.1 but with alpha drops as soon as we can 
  • IPy 3.0 supporting new CPy 3.0 after IPy 2.1, probably shorter than a typical major release

One last thing, as many of you know the IronRuby project supports community contributions to the standard libraries. I wanted the IPy community to know I'm 100% committed for establishing a similar arrangement for IronPython. I've got nothing to announce yet, but rest assured I've been spending a lot of time talking to lawyers.

As always, if you've got opinions to share please feel free to leave me comments below, shoot me an email, or join the IPy mailing list.

Posted By Harry Pierson at 5:05 PM Pacific Daylight Time

Tuesday, July 15, 2008

IronPython 1.1.2 RC

It's a little late, but we just pushed out the RC for IronPython 1.1.2. This is a minor release with a bunch of bug fixes we've backported from our 2.0 work.

However, there are two minor breaking changes I wanted to highlight:

  1. Work Item #16348 - We've changed the nt.unlink method so that it raises an exception if the file doesn't exist. This brings nt.unlink in line with CPython's behavior, but does change the public behavior of the method.
  2. Work Item #16735 - We've changed the return type of IronPython.Runtime.Operations.Ops.Id() from long to object. We return a boxed 32-bit integer for Ops.Id(), unless you've allocated over 2^32 objects in which case we roll over to our arbitrary precision IronMath.BigInteger type. Note, this only would affect statically typed languages compiled against the IronPython assembly. It wouldn't affect python  code in any way.

We think these are fairly minor (hence the reason we green-lit them) and furthermore these changes mirrors the eventual behavior of 2.0. Please let me know if either of the changes is a problem for you or your project.

Posted By Harry Pierson at 11:16 AM Pacific Daylight Time

Morning Coffee 168 - E3 Edition

Yesterday, was Microsoft's big reveal for Xbox 360 this coming holiday season. If you're not a gamer, please move along, nothing to see here. Also note, I work @ Microsoft, but not in the games division so this is only my thoughts on yesterday's announcements.

  • While several "hard-core" games were showcased - Fallout 3, Resident Evil 5, Fable 2, Gears of War 2 and the surprise announcement that Final Fantasy XIII - the rest of yesterday's briefing screamed "we're not just for hard core gamers!"  Call it the Wii effect. Even the title of the main E3 Press Release was Gameplay for Every Passion.
  • Honestly, my favorite announcement from yesterday wasn't game related at all - it was the announcement of Netflix on Xbox 360. I've been hoping for a flat rate subscription plan since Video Marketplace first launched. Soon, I'll have it.
  • I'm not sure what I think of the New Xbox Experience yet. On the one hand, the whole cartoon avatar thing isn't really my bag. Plus, isn't it quite the Mii clone? However, the ability to share photo and video viewing experiences - even with cartoony avatars - and the flashy + engaging navigation mechanism looks like a real improvement. Here's hoping they improve the performance of navigating hard drive content (games library, gamer pictures, etc).
  • Congrats to my friend Matt who's been very involved in the development of the new Primetime game show channel. I'm not that interested in "1 vs 100", but I think the potential of that game model is pretty huge. If they created a Jeopardy game for Primetime, I think my parents would by a 360 right away.
  • Music / party games seem to have been the primary focus of the press briefing. I'm definitely getting Rock Band 2 (AC/DC woot!) and I think my wife would like Lips (she usually sings when we play Rock Band). I want to see how the "wireless interactive microphones: Featuring stylish interactive motion sensors and lights" will work. Guitar Hero World Tour looks cool too, but I'm not re-buying all new music hardware.
  • You're in the Movies looks like a hoot, plus it doesn't really look like a game, so much as a "party activity". For example, while there are minigame winners or losers, "winning" takes a back seat to the final movie result. I'm guessing this will be big with the kids.
  • Speaking of kids, Patrick is really looking forward to Banjo-Kazooie Nuts & Bolts. He loves anything related to building, and building fantastic vehicles is a core part of the gameplay. As for Riley, I think she's getting old enough to enjoy Viva Pinata - she enjoys watching Patrick and I play - though I'm not sure we need the new Viva Pinata.
  • Geometry Wars 2 and Portal: Still Alive, both coming to Xbox Live Arcade. 'nuff said.
  • Not really "new" news, but XNA Community Games launches this fall. I've got a creators club membership, so I'm able to experiment with this now - it rocks, though the available games are pretty shall I say "unpolished" at this point.
  • Halo Wars not coming until 2009. :(
  • No new Bungie news, but their website is counting down to *something* tomorrow. I guess we'll find out then.
Posted By Harry Pierson at 10:42 AM Pacific Daylight Time

Monday, July 14, 2008

Morning Coffee 167

  • If you're a gamer, you're probably already well aware that E3 is this week. The Too Human demo has already been released. I have a friend who's been working on "something" that will be announced today (I think).
  • Live Mesh folks pushed out an update Friday. Among the new features is the ability to sync folders among peers but NOT up to the cloud. This is cool because it means I can sync my many many GB of pictures and music on my home machine backed up with Carbonite. This means I can sync them without blowing thru my 5GB Mesh storage limit.
  • It looks like there's a new F# drop - 1.9.4.19 - but as usual there is no announcement or details as to what's new. Release notes guys, look into it.  UPDATE - Don Syme blogged the release, and it's pretty minor. a .NET FX 3.5 SP1 bug fix, a fix for Mono, and they removed WebRequest.GetResponseAsync to make F# work on Silverlight. And the release notes are in the readme. My bad.
  • Speaking of F#, it was "partially inspired" by OCaml, so when I see papers related to OCaml, I immediately wonder if I an apply the described techniques to F#. "Catch me if you can, Towards type-safe, hierarchical, lightweight, polymorphic and efficient error management in OCaml" is one such paper. (via LtU)
  • Speaking of functional programming, Matthew Podwysocki posted a bunch of FP links as well as a Code Gallery Sample on FP in C#. Good stuff.
  • As per Scott Guthrie, it looks like there's a new ASP.NET MVC drop coming this week.
  • Based on posts by Ted Neward, Dare Obasanjo and Steve Vinoski, Google Protocol Buffers sounds like it's going to be a dud. Note, I haven't looked at it depth personally, I'm just passing on opinions of some folks I read and trust.
  • Speaking of Dare, both he and James Hamilton take a look at Cassandra and come away impressed. I wonder how easy it is to code against from Python and/or .NET?
  • Bart de Smet has a cool sample of calling out to PowerShell from IronRuby via the backtick command. Pretty cool, but it would even cooler to show how to call out to PS and return .NET objects to Ruby (though that would probably not be spec compliant for the backtick command).
  • Here's a MS code name I had never heard before - Zermatt. It's "a framework for implementing claims-based identity in your applications." (via Steve Gilham)
Posted By Harry Pierson at 9:30 AM Pacific Daylight Time

Monday, July 07, 2008

Morning Coffee 166

Yes, I realize it’s been a while. I tried in vain to catch up with my blog reading after my Hawaii vacation and finally just gave up and hit “mark all as read”.

Dynamic Languages

  • There's a new version of the DLR hosting spec available (doc, pdf). The DLR implementation is still in motion, so there are some inconsistencies between the spec and the code, but the spec should give you the high level overview you need if you want to host DLR languages inside your app.
  • Oleg Tkachenko recently joined the dynamic languages team. He's the creator of the Interactive IronRuby Web Shell, an IronRuby version of Try Ruby. Of course, it’s not as cool as using SL2to execute the code directly in the browser. Michael Foord has his Python in the Browser and my teammates John and Jimmy demoed a Silverlight version of Try Ruby @ TechEd.
  • Jim Deville, also of the dynamic languages team, recently started blogging.
  • I have a new boss, Dave Remy. He doesn't have a blog - yet - but you can follow him on Twitter as daveremy. When Twitter is actually working that is.
  • There's a new homepage/wiki for IronRuby though I’m not sure why there's a picture of Matz wearing a Python shirt on the home page.
  • My teammate Jimmy Schementi provides some "continued hope" for a better (heck, I'll take current) ASP.NET and ASP.NET MVC story for DLR languages.
  • Via Michael Foord, sounds like IronClad is making good progress. V0.4 can run the bz2 module "in its entirity" (maybe run a spellcheck on your site, guys?) and now apparently, it's now able to load numpy.core. Very exciting!

Other Stuff

  • Pat Helland, who has blogged even less than me for the past few months, has a post up about controller and doers in the IT department. After 18 months in MSIT, put me in the doer camp, please.
  • The F# team has pushed out a spec for v1.9.4 of the language. Don Syme says it's not official, but it's a huge improvement over the old informal spec
  • Speaking of F#, my friend Matthew Podwysocki recently published FsTest, a testing DSL for F#. I wrote about F# unit testing as part of my PEG parsing series, and I really like the direction Matthew has taken this project. You can pull it down from CodePlex.
  • When I did my PEG talk @ Lang.NET, Gilad Bracha mentioned I should check out oMeta. It looks really cool, though with the job change I haven’t had the time to play with it. Now I discover that Jeff Moser is working on a version for CLR called oMeta# that I’ve got to spend some time with. And in the comments to that post, I discovered pyMeta from Allen Short, though it apparently doesn’t work on IronPython (must investigate why).
  • James Kovacs introduces psake, a PowerShell based build automation tool which uses a rake-inspired internal DSL syntax similar to one I blogged last year. I'd love to see this take off, but given MSBuild's tool integration, I wonder if that's feasible.
  • I upgraded my home wireless network almost exactly a year ago. I've been happy with the range and coverage, but not so happy with the Buffalo Tech firmware. The built-in DHCP server is pretty flaky. So I upgraded to the open-source Tomato firmware. Upgrade was smooth, though I did need to reset my cable modem. But even that was smooth - Comcast has an automated service for that now,
Posted By Harry Pierson at 9:30 AM Pacific Daylight Time

Tuesday, July 01, 2008

Programming Languages @ PDC08

The PDC folks pushed out a bunch of new sessions yesterday, including a bunch from my part of DevDiv. You can see the full list of sessions that have been published (so far) at the PDC site.

An Introduction to F#
Learn about Microsoft's new language, F#, a typed functional programming language for the .NET Framework. F# combines functional programming with the runtime support, libraries, tools, and object model of .Net. Understand how F# asynchronous workflows help tame the complexity of parallel and asynchronous I/O programming and how to use F# in conjunction with tools such as Parallel Extensions for .NET.

Deep Dive: Dynamic Languages in .NET
The CLR has great support for dynamic languages like IronPython. Learn how the new Dynamic Language Runtime (DLR) adds a shared dynamic type system, a standard hosting model, and support for generating fast dynamic code. Hear how these features enable languages that use the DLR to share code with other dynamic and static languages like VB.NET and C#.

Future Directions for Visual Basic
Come learn about the new capabilities in the next version of the language, including: extensions to LINQ, syntax simplifications, and improvements to the IDE. We'll provide insight into the direction of the language, including dynamic binding, meta-programming, and scripting.

The Future of C#
In this talk Microsoft Technical fellow and C# Chief Architect Anders Hejlsberg outlines the future of C#. He will describe the many forces that influence and shape the future of programming languages and explain how they fit into C#.

Visual C++: 10 is the New 6
Get more done. The next version of Visual C++ is all about improving developer productivity for large-scale applications. Learn about the IntelliSense and browsing experiences, changes to the project and build system, project-less browsing, collaboration through remote symbol indexing, and custom visualization of symbolic information.

Posted By Harry Pierson at 10:37 AM Pacific Daylight Time
C# | C++ | Lanugages | DLR | F# | IronPython | IronRuby | Microsoft | PDC08 | Visual Basic
Change Congress
Recent Bookmarks
Tags .NET Framework (2) __clrtype__ (9) ADO.NET (5) Agile (7) AJAX (3) Architecture (284) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (93) Web Services (5) ASP.NET (24) Azure (1) Battlestar Galactica (3) BI (2) BizTalk (4) Blogging (117) dasBlog (11) Podcasting (4) BPM (1) C# (11) C++ (4) Capitals (5) CardSpace (3) CLR (2) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Debugger (18) Dependency Injection (2) Development (119) C Plus Plus (1) Embedded (5) Lanugages (40) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (19) Domain Specific Languages (15) Durable Messaging (5) Dynamic Languages (10) Dynamic Silverlight (1) Education (3) Enterprise 2.0 (1) Entertainment (14) ETech (15) F# (51) Functional Programming (17) Game Development (2) Guidance Automation (3) Hardware (8) HawkEye (3) Health (1) Hockey (31) Home Electronics (1) Home Network (5) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (92) IronRuby (13) Java (2) Job (3) Kodu (1) LangNET (2) LINQ (23) Live Framework (3) Live Mesh (2) Lost (1) Master Data Management (1) Media 2.0 (6) Microsoft (31) MIX06 (2) Mobile Phone (1) Monads (5) Morning Coffee (172) Object Oriented (4) Office (5) Open Source (7) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (33) Games (18) General Geekery (26) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (17) Parallel Programming (3) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (5) Politics (48) PowerPoint (2) PowerShell (37) Presentation (5) Projects (1) HawkWiki (1) Python (6) Quote of the Day (4) Refactoring (1) Research (2) REST (18) Reuse (5) Robotics (2) Rock Band (4) Rome (5) Ruby (23) Ruby on Rails (1) Sci-Fi (2) Scripting (4) Security (3) Service Broker (14) SharePoint (2) Silverlight (20) Social Software (1) Software + Services (2) Software Design (1) Software Factories (11) Software Industry (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (6) Unified Client (1) Unit Testing (4) USC (1) UX (1) Virtual PC (2) Visual Basic (2) Visual Studio (20) Volta (2) Washington Capitals (37) WCF (31) Web 2.0 (65) Web Services (5) WF (21) Windows (1) Windows Live (28) Windows Live Writer (2) WPF (7) Xbox (1) Xbox 360 (54) XML (11) XNA (15) Zune (4)
Disclaimer: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion.