Practical Parsing in F#

I’m interested in parsing because I’m interested in Domain Specific Languages. F# is pretty good for internal DSLs, but internal DSLs are obviously limited by the syntax of the host language. If you want complete control over the language, you’ve got to build your own parser.

The defacto standard for parser development is Yet Another Compiler Compiler, or yacc. There’s a version of yacc for .NET as well as one specifically for F#. However, I’m not a fan of yacc. Yacc parsers are specified using context-free grammar (aka CFG). But CFG’s can be ambiguous – actually, it’s nearly impossible to build an unambiguous CFG. Personally, I’m a big fan of Parsing Expression Grammars (or PEGs) which among other advantages makes it impossible to develop ambiguous grammars. Furthermore, PEGs don’t require a separate lexical analyzer like lex, so I think they’re more suitable for building modular compilers.

Since I like PEGs and F# so much, I developed a parser for the PEG grammar from the original PEG whitepaper using F#. The grammar is much simpler than a language like C#, but with twenty nine grammar productions it’s certainly not trivial. The F# implementation is fairly straightforward backtracking recursive decent parser, which makes it easy to understand even if you’re not a parser guru. It’s also small – around 400 lines of code including comments. But I think the code illustrates both the general value of Functional Programming as well as the specific value of F#. Here’s how the series is shaping up (though this is subject to change):

I was originally planning to post the code for the parser itself with this post. However, i find that I’m revising the code as I write the articles in this series, so I’m going to hold off for now. If you’re really desperate, drop me a line and I’ll see what I can do.

Update: Almost forgot, if you’re going to follow along at home, I’m using the latest version of F#, v1.9.3.7. Note, the F# Downloads page on the MS Research is woefully out of date, so go to the MS Research Downloads page. Currently, it’s the most recent release. It snaps into VS 2005 and 2008 plus has command line tools. If you’re an VS Express user, Douglas Stockwell explained how to roll your own F# Express.

Much Later Update: The code is now available on my Skydrive.

Morning Coffee 129

  • Short coffee this morning, as I’m home with a tweaked ankle.
  • I started playing Indigo Prophecy over the weekend. It’s an original Xbox game, released as part of the new Xbox Originals program. It has a good metacritic score (84), though apparently it wasn’t much of a retail success. I’m enjoying it, though it’s not very challenging. It’s more an interactive movie than a game. Good story, though.
  • The ASP.NET MVC preview dropped today, Scott Guthrie has the details. Scott Hanselman has a 40 minute how-to video and Phil Haack has severalarticles up already.
  • Speaking of ASP.NET MVC and Scott Guthrie, he’s got another post in his series on ASP.NET MVC. This time, he’s covering how to handle form input / POST data.
  • Erik Meijer has posted some of his thoughts on Volta. He’s one of the guys behind Volta, so it’s worth a good look. (via Dare Obasanjo)
  • Late Addition – the ASP.NET Extensions is more than just the MVC stuff. It also includes AJAX improvements, Silverlight support, ADO.NET Data Services and ASP.NET Dynamic Data Support. Data Services (formerly Astoria) let’s you easily expose your database via RESTful services. I think Dynamic Data Support used to be code named Jasper. It’s a “rich scaffolding framework” for ASP.NET. I assume that’s to compete w/ Ruby on Rails.

Blogging F# Code

I’m going to start posting about my F# parsing code soon. Obviously, I’ll make the code directly available, but I’m also going to be writing about it quite a bit. Since I’ll be posting lots of F# code snippets, I took the time to build an F# language syntax definition for CodeHTMLer. Of all the various WL Writer Insert Code plug-ins, CodeHTMLer is my favorite because it can be configured not to use <pre> tags, which many RSS readers handle poorly (in my experience).

In case anyone else wants it, I’ve stuck the CodeHTMLer F# language definition up on my SkyDrive. If you using the CodeHTMLer WL Writer Plug-in, you can easily add this to your machine. Once you’ve installed CodeHTMLer and run it once, go to the command line and type cd %appdata%WindowsLiveWriter and you’ll find the LanguageDefinitions.xml file. Edit that file to insert the add the contents of my F# language definition after the <CodeLanguages> tag and you’re all set.

BTW, the first language in the file will be the default language in the plug-in, so if you’re an occasional F# user, you might want to add the F# definition to the end rather than the beginning of the file. If you don’t want to further edit the XML file manually, you can select “Edit Languages” in the plug-in and edit the order of the languages to your heart’s content.

Morning Coffee 128

  • After using Outlook 2007 as my RSS reader for a few months, I’ve gone back to RSS Bandit. I run two work machines (desktop + laptop) and I finally got tired duplicated blog entries because each copy of Outlook downloads the same post. Also, for some reason Outlook downloads the same Technorati posts over and over again.
  • ADO.NET Entity Framework Beta 3 was released. The latest CTP of the EF Tools is also available. And as per the press release, EF has gained support from “Core Lab, DataDirect Technologies, Firebird Foundation Inc., IBM Corp., MySQL AB, Npgsql , OpenLink Software Inc., Phoenix Software International, Sybase Inc. and VistaDB Software Inc”. I’m not sure what that means, exactly, but I guess you’ll be able to LINQ to Entities on a wide variety of DB platforms. Interesting Oracle isn’t on that list. Not really surprising, but interesting.
  • Here’s a new ASP.NET MVC article from Scott Guthrie, this one on views and how you pass data to one from a controller. Using generics to get strongly-typed ViewData is pretty sweet. But where’s the MVC CTP that was supposed to be here this week?
  • In news about web app tool previews that did ship this week, Live Labs announces Volta. Haven’t installed or played with it yet, but I did read the fundamentals page. It primarily looks like a tool to compile MSIL -> JavaScript, so you can write your code in C# but execute it in the browser. Sam and Jesus are excited, Arnon not so much. Arnon’s argument that being able to postponing architectural decisions is to good to be true is fairly compelling, and not just because he quotes me to support his argument. But I’ll download it and provide further comment after I experiment with it myself.
  • Simple Sharing Extensions is now FeedSync. Not sure what else is new about it, other than it’s been blessed with “1.0″ status. The Live FeedSync Dev Center has an introduction, a tutorial and the spec. (via LiveSide)
  • Dare likes tuples. Me too. I also like symbols.

Durable and RESTful

A while back I wondered if it’s still REST if you don’t use HTTP. The reason I wondered that is because like many I’ve become disillusioned with the WS-* stack over time and see REST as a viable alternative to all that spec-driven complexity. However, just because I’m looking to REST means I’m willing to give up on durable messaging. So I shouldn’t be asking “can I do REST without HTTP?” I should be asking “what protocol can I use to do durable messaging with REST?”

It turns out HTTP is just fine for RESTful durable messaging, if you take the time to make your POSTs idempotent. There’s even a IETF RFC that builds on HTTP and specifies a mechanism to do it.

As I wrote last month, idempotence is critically important to ensuring “things” happen exactly once when connecting disparate systems together. At the end of that post, I asked you, dear reader, to contemplate just how durable messaging systems ensures exactly once delivery. They do it by assigning messages to be delivered a unique identifier. Any non-idempotent operations can be made idempotent with unique identifiers and a message ID log.

“Not Idempotent:
Withdrawing $1 Billion.
Idempotent:
If Haven’t Yet Done Withdrawal #XYZ for $1 Billion,
Then Withdraw $1 Billion and Label as #XYZ”
Pat Helland

For example, when you send a message in MSMQ, it’s assigned a 20 byte identifier which is “unique within your enterprise.” 1 If the destination system receives multiple messages with the same message ID, it knows they are duplicates and can safely toss all but one of the messages with the same ID. Exactly once, no transactions.

While many operations in REST are naturally idempotent, using REST doesn’t magically make all your operations idempotent, contrary to popular belief. Have you ever seen a message like “please don’t press submit order twice” on the checkout page of an e-commerce website? It’s there because POST is not naturally idempotent and the site hasn’t taken any extra steps to identify duplicate POSTs. If the site embedded a unique ID in a hidden form field, it could use that to identify duplicate orders.

If you’re a RESTifarian, haven’t you seen this approach somewhere before?

Given that POST isn’t naturally idempotent, I think it’s kinda surprising that new resources are created in AtomPub by POSTing them to a collection rather than PUTting them to a specific URL. RESTful Web Services specifically points out that PUT is idempotent, so I wonder why AtomPub uses POST. I’d guess most AtomPub implementations (aka blogs) aren’t much concerned about ensuring Exactly Once. If an blog entry gets posted twice, you delete one and go on with your life.

However, if you wanted to use AtomPub and ensure Exactly Once, you can use the fact that Atom entries must contain exactly one ID element which as per the spec must be universally unique. From reading the Atom spec, the ID element seems primarily designed for Atom feed consumers, but AtomPub servers could also use it as an “idempotence identifier”, similar to how MSMQ uses the message ID. If you end up with multiple entries with the same entry ID, discard all but one.

So by creating a unique identifier on the client side and logging that identifier on the server side, we can make any REST service idempotent. We can make it a durable service if we write the outgoing message – with the message ID we generate – to a durable store before trying to send it. If you write it to a durable store within the scope of a local transaction, you’re even closer to duplicating MSMQ’s functionality, yet the only protocol requirement beyond vanilla HTTP is having a unique message ID.

The one problem with the Atom entity ID approach is that it requires cracking the message in order to see if we should process it. For REST services, I would think we’d want to stick the idempotence identifier in an HTTP header. We already headers to implement conditional GET, why not a header for what amounts to conditional POST?

Turns out such a header exists in the AS2 spec, i.e. “MIME-Based Secure Peer-to-Peer Business Data Interchange Using HTTP”. AS2 defines a Message-Id HTTP header which “SHOULD be globally unique”. In the case of an HTTP error, AS2 specifies the “POST operation with identical content, including same Message-ID, SHOULD be repeated” and that “Servers SHOULD be prepared to receive a POST with a repeated Message-ID.” I assume this implies a server shouldn’t process a message with the same ID twice.

So what would a durable REST service look like? I think like this:

  1. Sending system records the intent to send a message by saving it to a local durable store, potentially in the scope of a local transaction. As part of saving the message, a unique message id is generated (I’d use a GUID, but as long as it’s unique it doesn’t matter.)
  2. A background thread in the sending system monitors the durable message store. When a new to-be-sent message arrives, the thread POSTs it to the destination, setting the Message-Id HTTP header to the unique identifier generated in step 1.
  3. The receiving system stores the Message-Id header value in a log table and processes the received message, potentially in the scope of a local transaction. Optionally, it can store the return message (if there is one) in the durable store as well.
  4. If the sending system doesn’t receive a 2xx status code, it rePOSTs the message to the receiving system until it does.
  5. If the receiving system receives a message that’s already listed in the log table, it ignores it and returns a success status code. Optionally, if the return message has been saved, the receiving system can resend the return message as long as it doesn’t redo the work.

This seems like a better approach than my original direction of doing REST over a durable protocol like MSMQ or SSB. What do you think?

Update: Erik Johnson points out that an HTTP POST’s idempotency is “left unsaid”. So my statement that “POST isn’t idempotent” isn’t quite correct. POST isn’t naturally idempotent. I’ve updated the post accordingly.


  1. Technically, the MSMQ message ID isn’t universally unique as it is a 16 byte GUID representing the source system + a 4 byte sequence number. The sequence number can rollover, after sending 2^32 messages. In practice, rolling over the message ID after 4 billion messages is rarely an issue.