Sunday, November 18, 2007

My first F# program

In previous hopes of getting an interview with the nascent F# team (which I obviously did not get; sad faces all around), I started adding F# blogs to my feed, including a former C# PM who I had the privilege of working with during my internship and ICFP 2006, Luke Hoban (not Luke H on my links). Jomo Fisher, a new developer on the F# team, posted a small challenge to "pivot" a list of lists in a small number of lines in any language. The goal is to be as concise and clean as possible, while beating his solution and a yet-to-be-posted solution, which are 9 and 4 lines of F# respectively. I came up with my first F# program after awhile (it looks like I just copied someone else's on the comments list, but comments are moderated so they weren't all there), which was kind of fun:

let rec pivot(l: 'a list list) =
    match List.hd l with
        | head::tail -> [for sub in l -> List.hd sub]::pivot [for sub in l -> List.tl sub]
        | [] -> [];;

Possibly due to my amateurism in functional programming or unfamiliarity with F#, these four lines took me quite awhile to figure out (more than an hour). Of course, reading the code is easy enough; I wonder if functional code exhibits hard-to-write, easy-to-read behavior in more than just this case. Of course, my solution is not quite the best, since my pattern matching operates on the head of the list. It's probably better to match the list with []::_ and _, which was someone else's solution.

Imperative code for this in the comments have been predominantly larger than 4 lines, with a C# with LINQ solution being the shortest. What other tricks can people come up with? I think the zip use in Python is interesting. It accomplishes the problem in one line by unpacking the list of lists and sending it to zip, a built in function that does transposition. Of course, zip is basically the problem objective so it seems kind of like the cheap way out; the use of Python's * operator to unpack the list makes it quite easy to do; F# has List.zip, but I have no idea if it can unpack the list like Python can.

In other news, I finally got F# to work with Mono on my Linux computers; turns out all that I needed to do is install some libraries.

No comments: