Saturday, April 28, 2012

Odd br tags being inserted before and after VSPaste code when submitting blog post from Windows Live Writer 2011 to Blogger

The title says it all. I’m not sure if this is a problem with Windows Live Writer 2011 or Blogger, but I think it is Blogger’s issue because when I view source in WLW, it doesn’t show the breaks, they only appear after submission to Blogger. Indeed, I’ve been struggling against Google’s recent changes to Blogger, such as difficulties using my custom blog template I create for Project Euler for F#un to this, newer blog (I mean, sheesh, I only created the thing two years ago, would hope it wouldn’t obsolete ever, let alone so soon!).

Anyway, the solution was to edit the blog post through Blogger’s online editing tools, and remove the br tags from the source edit view there.

Quick way to convert a space delimited list to a literal F# data structure

Today, while working on this Unquote issue, I needed to create a literal set of reserved words from a space delimited list found in the F# 2.0 specification. Thanks to the F# interactive and it’s printer, I didn’t need to manually create the literal set by laboriously inserting quotations around each word.

First, I copied and pasted the list of words from the specification into a .fs file and easily made it into a literal multi-line string. Taking care to add an extra space at the end of each line so that the last and first words of two consecutive lines didn’t run together when ultimately split.
let reservedWords = "\
    atomic break checked component const constraint constructor \
    continue eager fixed fori functor include \
    measure method mixin object parallel params process protected pure \
    recursive sealed tailcall trait virtual volatile"

I submitted that to FSI.
val reservedWords : string =
  "atomic break checked component const constraint constructor c"+[156 chars]

Then, in FSI, I set the fsi.PrintLength to 1000 so that I could see the complete list in the output and split by ‘ ‘ and converted to a set.
>  fsi.PrintLength <- 1000;;
val it : unit = ()

> reservedWords.Split(' ') |> set;;
val it : Set<string> =
  set
    ["atomic"; "break"; "checked"; "component"; "const"; "constraint";
     "constructor"; "continue"; "eager"; "fixed"; "fori"; "functor"; "include";
     "measure"; "method"; "mixin"; "object"; "parallel"; "params"; "process";
     "protected"; "pure"; "recursive"; "sealed"; "tailcall"; "trait";
     "virtual"; "volatile"]
You can see that the resulting FSI output is directly usable F# code completing my task.

Sunday, April 15, 2012

Experimenting with precompiled regexes in Unquote

Today I spent some time experimenting with precompiled regexes in Unquote: https://unquote.googlecode.com/svn/branches/precompiled-regex. However, I was not able to show any measurable performance improvements from this work. Perhaps this was to be expected, considering Unquote only uses 5 compiled regexes currently and the upfront cost of compiling those on the fly must be small compared to the actual regex matching performed across all of Unquote’s nearly 500 unit tests (though Unquote uses a relatively small number of regexes, they are used frequently). So, for now, we’ll stick with normal compiled-on-the-fly regexes, unless we gain a large number of regexes in the future. But, it is worth noting the compiling on-the-fly does increase the performance of Unquote by 2x.

Friday, April 13, 2012

FsEye 1.0.1 released

FsEye 1.0.1 has been released. This is a maintenance release that only included a couple bug fixes (but critical if you wish to inspect any objects with setter only properties).

Thursday, April 12, 2012

Unquote 2.1.1 released

After an 8-month break, a new version of Unquote has been released. This is mostly a maintenance release, but notable features and bug fixes include the addition of the raisesWith operator, and improved printing of function and None values. See the release notes for a full listing.

Note that the Unquote logo will not be visible on the NuGet gallery this release, due to a change in the way NuGet allows managing packages.

For myself and possible future developers, I’ve also updated the Unquote solution to use NuGet package reference wherever possible and enabled “NuGet package restore” on the solution so that packages don’t need to be committed to the source repository. However, solution level packages such as Statlight tools for running Silverlight tests don’t seem to be restoring. I’ll have to look into that later. For libraries such as NUnit Silverlight builds which don’t have NuGet packages, I’ve committed those to the source repository under a lib folder.

Tuesday, April 10, 2012

Convert Outlook formatted email addresses to Gmail format

Recently, I wanted to send an email from my personal Gmail account to a group of folks at my office. At the office, we use Outlook. So within Outlook, I entered all the email address in the “To” box and pressed “Check Names” to assert their validity and convert them into Outlook’s canonical format. I then copied and pasted those email address into the body of an email and sent it to my Gmail account for future use.

But alas, when it came time to send the email from my Gmail account to the Outlook formatted email addresses I had collected earlier, I got a send error due to Gmail’s inability to parse Outlook’s format. I had about 15 email addresses in the list, and decided it would be more fun to parse out the email addresses using a regex than to manually extract them.

Of course, I chose F# for the job, since, besides generally being my favorite go-to language, it is perfect for these quick interactive scripting scenarios. The following is the code snippet I came up with, which worked nicely as advertised.

open System.Text.RegularExpressions
let raw = @"John, Smith-Anderson <JohnS@Company.com>, Reg, Ex <RegE@Company.com>, Hello, World <HelloW@Company.com>"
let regx = new Regex(@"<([^<>]*)>")
let matches = regx.Matches(raw)

matches
|> Seq.cast<Match>
|> Seq.map (fun m -> m.Groups.[1].Value)
|> String.concat "; "
//val it : string = "JohnS@Company.com; RegE@Company.com; HelloW@Company.com"

The Purpose

During my adventures in coding, I often solve problems worth remembering but not worth dedicating an entire blog or open source project to. Thus is the purpose of this blog.