Passion * Technology * Ruthless Competence

Thursday, November 29, 2007

F# Hawkeye : Pattern Matching

(Harry is @ DevTeach in Vancounver with his family this week. He was hoping to still do Morning Coffee posts, but that's turned out to be infeasible. So instead, you get a series of pre-written posts about F#.)

Most FP languages include some type of pattern matching, and F# is no exception. At first blush, pattern matching looks a little like a switch statement, but it's much more powerful. Where switch statements typically only do simple matches such as "does this variable equal this constant?". In F#, you can break apart types, use wildcards even pass the potential match data into a custom function to determines if there's a match. Of course, you can also do your more run-of-the-mill "does value equal constant" comparisons as well.

The problem with most functional language is that while pattern matching is powerful, it's not particularly extensible. As Don pointed out in a recent paper, this becomes a real problem when trying to integrate FP with OO. OO is designed to hide details behind abstractions. Yet those abstractions can't be used in pattern matching. Luckily, Don and the F# Guys (sounds like a band) have invented an extensible pattern matching syntax called Active Patterns to deal with this problem. Basically, in more recent versions of F#, you can adorn functions with special syntax so that you can use them in your pattern matching clauses.

This turns out to be wicked cool for writing parsers. I'm building recursive descent parsers, so each grammar production is implemented as a function. Yet, since I'm using the active pattern syntax, I can use them in pattern matching clauses. This allows me to chain together functions in a single match clause rather than having multiple match statements. And it's very readable. For example, the function to recognize the grammar production "Additive  <- Multitive ‘+’ Additive | Multitive" is translated into the following F#:

and (|Additive|_|) input = 
    match input with 
    | Multitive(v1,Token '+' (Additive(v2, input))) ->
          Some(v1+v2,input)
    | Multitive(v,input) -> Some(v,input)
    | _ -> None

The weird "bananas" around Additive on the first line indicate this is an active pattern. Multitive and Token are also an active patterns. This syntax is a little parens heavy, but otherwise, that translation from grammar to F# is nearly declarative. It almost defeats the need for having a parser generator when building a parser is this straightforward. Almost.

Posted By Harry Pierson at 7:40 AM Pacific Standard Time
Saturday, December 01, 2007 9:05:36 PM (Pacific Standard Time, UTC-08:00)
Out of curiosity, are you able to post any of your parser code? I'm only just getting into F# as and when I have spare time - but I'm interested in if/how you tokenize your input string using F# code before parsing the stream of tokens via pattern matching - I've been attempting to use regex Active Patterns so far, and the results aren't pretty (possibly because I haven't quite "grokked" how best to use Active Patterns to their full potential).

Keep up the good posts on F#!

Chez,

- Alex
Monday, December 03, 2007 11:07:43 AM (Pacific Standard Time, UTC-08:00)
Will do - just let me get caught up at work first!
DevHawk
Saturday, December 08, 2007 7:27:23 AM (Pacific Standard Time, UTC-08:00)
Does your weaponly also comprise such elements as "nice red uniforms"?

I'd love to see the parser, too, as I'll soon be embarking on one of my own, though I'll be using fslex and fsyacc for practice. I'll post about it. The Active Pattern thing is mind-blowing.
Saturday, December 08, 2007 3:58:02 PM (Pacific Standard Time, UTC-08:00)
I didn't expect a kind of Spanish Inquisition! :)
DevHawk
Monday, December 10, 2007 11:29:03 AM (Pacific Standard Time, UTC-08:00)
I'm interested in generating various classes of pictures using grammars.

I've worked through the included intro fslex fsyacc examples from Microsoft, Foundations of F#, and F# Journal; each has its'differences.

Just ordered F# Expert, and considering geting OCaml book.
I'm always interested in more intelligible code examples.

Glad to find you're a resource.
Art Scott
Comments are closed.
Change Congress
Recent Bookmarks
Tags .NET Framework (2) __clrtype__ (9) ADO.NET (5) Agile (7) AJAX (3) Architecture (288) Guidance (6) Interop (2) Modelling (61) Patterns (7) Process (4) SOA (94) Web Services (5) ASP.NET (25) Async Messaging (2) 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) CodePlex (1) College Football (10) Comedy Central (1) Community (81) Concurrency (6) Consumer Electronics (1) Database (13) Debugger (23) Dependency Injection (2) Development (122) C Plus Plus (1) Embedded (5) Lanugages (42) Media (2) P2P (11) Rotor (1) SharePoint (6) SOP (3) DIY (1) DLR (25) Domain Specific Languages (15) Durable Messaging (5) Dynamic Languages (12) 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) HawkCodeBox (1) HawkEye (3) Health (1) Hockey (31) Home Electronics (1) Home Network (5) Hosting API (1) Humor (5) IASA (1) Idempotence (3) infrastructure (5) Instrumentation (4) Integration (2) IronPython (112) IronRuby (16) Java (2) Job (3) Kodu (1) LangNET (2) Lightweight Debugger (5) 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 (8) Open Space (2) Operations (3) Other (135) Art (1) Books (1) Family (33) Games (18) General Geekery (27) Home Theater (1) Movies (23) Music (20) Politics (3) Society (1) Sports (37) Working at MSFT (19) Parallel Programming (3) Parsing Expression Grammar (16) patterns & practices (2) PDC08 (5) Politics (48) Polyglot (3) PowerPoint (2) PowerShell (39) Presentation (7) Projects (1) HawkWiki (1) Pygments (5) 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 (2) Software Engineering (1) Software Factories (11) Software Industry (1) Space Elevator (1) Spark (1) SQL Server (2) Stephen Colbert (1) TechEd (7) TechEd06 (1) TechRec League (1) Television (6) Travel (7) Unified Client (1) Unit Testing (4) USC (1) UX (1) Virtual PC (2) Visual Basic (3) Visual Studio (20) Volta (2) Washington Capitals (37) WCF (31) Web 2.0 (67) Web Services (7) WF (21) Windows (3) Windows Live (29) Windows Live Writer (3) WPF (8) 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.