Monday, February 25, 2008
I had resisted advertisements on this blog for a long, long while. It's not that I have anything in particular against ads. I think it's reasonable for a blogger to add advertising to offset the cost (mostly time) of maintaining a solid blog. I just hate it when nice, clean-looking blogs start to look like this:

Nascar Ads

I suppose that I share a lot of the same sentiments on the subject as Jeff Atwood over at Coding Horror.

About a month ago, I added Google AdSense (at the suggestion of my good friend Keith Elder). I've tried to keep the ads relatively low key in order to keep the clutter down. That doesn't result in as many clicks as it might if I threw them in your faces, but I'm OK with that. I like to keep my layout clean for those who do come in via the web (and not just the feed).

The truth is, I don't trust Google AdSense all that much. Context-sensitive ads are great, but they aren't always accurate. For example, I've mentioned the word "Haskell" several times in reference to the pure functional programming language, Haskell. However, the very use of this relatively uncommon word has triggered Google Ads for the Haskell Indian Nations University. Sigh. It's really hard to get behind advertised products when you're not 100% certain that they'll be relevant to your content.

Recently though, I found a product that I can whole-heartedly recommend. It's a product that falls directly into my demographic of humor-loving, technology-lusting geeks: RiffTrax.

What's RiffTrax you ask? Well, do you remember the TV show Mystery Science Theater 30001? That's right. The one with the guy and the robots and the making fun of old B-movies. Well, RiffTrax is that without robots and with blockbusters instead of B-movies. It still has the guy though. In fact, it's the same guy from MST3K.

In essence, RiffTrax are feature-length commentaries in MP3 format that you can purchase, download and sync to your DVDs. Some RiffTrax feature stars and writers from MST3K, and some even have celebrities joining in on the fun. For example, my current favorite is a riff on Jurassic Park that features none other than Weird Al Yankovic.

Pants-wettingly hilarious. Seriously.

Below is a small sampling of the films that have received the RiffTrax treatment. There are lots of others. Some have Jar Jar Binks. Some have Keanu Reeves. All will make you howl with laughter.

Honestly, I don't think of this as advertising. This is a public service announcement. You need this. I promise.

1Some may have missed out on the delights of Mystery Science Theater 3000 (MST3K). You can catch up here.

posted on Monday, February 25, 2008 6:44:36 PM (Pacific Standard Time, UTC-08:00)  #    Comments [1]

kick it on DotNetKicks.com
Welcome to the eighth article in my series about why I look upon the F# language with the hormone-driven lust of a 16-year old boy. ([ed.] Dustin's trophy wife has indicated that the previous metaphor might be a little too vivid.)

If you're just joining us, below is the path that has brought us to this point.

  1. The Interactive Environment
  2. Type-safe Format Strings
  3. Tuples
  4. Breaking Up Tuples
  5. Result Tuples
  6. Functions, Functions, Functions!
  7. Pattern Matching

Today, we're taking a high-level look at F# option types. Option types are a simple example of a discriminated (or tagged) union1, although understanding that isn't necessary in order to use them. Simply put, an option type wraps a value with information indicating whether or not the value exists. For C# or VB programmers, it may be convenient to think of option types as a mutant cross between .NET 2.0 nullable types and the null object design pattern.

There are two constructors that instantiate option types. First, there's the Some constructor, which takes a value to be wrapped.

> let someValue = Some(42);;

val someValue : int option

And then, there's the None constructor, which doesn't take anything.

> let noValue = None;;

val noValue : 'a option
NeRd Note
Notice that, in the above code, F# infers the type of noValue as the generic, 'a option, rather than int option. That's because, unlike the declaration of someValue, no information indicates an int. If you really want to declare a None value as type int option, you'd declare it like so:
> let noValue : int option = None;;

val noValue : int option

One of the properties of option types that makes them so compelling is the ability to pattern match over them.

> let isFortyTwo opt =
-   match opt with
-   | Some(42) -> true
-   | Some(_) -> false
-   | None -> false;;

val isFortyTwo : int option -> bool

Now, we can call our isFortyTwo function to show that the pattern matching works as expected.

> isFortyTwo someValue;;

val it : bool = true

> isFortyTwo noValue;;

val it : bool = false

> isFortyTwo (Some(41));;

val it : bool = false

This is all well and good, but we need a practical example to sink our teeth into. Let's use the .NET Framework Stream.ReadByte function as a guinea pig. ([ed.] Dustin is not implying that you should sink your teeth into guinea pigs. That's disgusting. Shame on you.)

Stream.ReadByte has a pretty bad code smell. First of all, it returns an int instead of a byte. Initially, that should seem strange since the method specifically states that it's a byte generator. ReadByte returns -1 when the current position is at the end of the stream. Because -1 is not expressible as an unsigned byte, ReadByte returns an int. Of course, that's the second problem: extra non-obvious information is encoded into the result value of this function. However, unless you read the documentation, there's no way of knowing that.

By employing an option type, we can clarify the function and be a bit more honest about its result.

> open System.IO
-
- let readByte (s : #Stream) =
-   match s.ReadByte() with
-   | i when i < 0 -> None
-   | i -> Some(Byte.of_int i);;

val readByte : #System.IO.Stream -> byte option

Now, the semantics of the function are better expressed thanks to the option type.

In addition, we can write a function that pattern matches over the result of our readByte function.

> let rec printStream s =
-   match readByte s with
-   | Some(b) ->
-       printfn "%d" (Byte.to_int b)
-       printStream s
-   | _ -> ();;

val printStream : #Stream -> unit

And here's the above printStream function in action:

> let bytes = [|1uy .. 10uy|];;

val bytes : byte array

> let memStream = new MemoryStream(bytes);;

val memStream : MemoryStream

> printStream memStream;;
1
2
3
4
5
6
7
8
9
10
val it : unit = ()

Option types provide an elegant way to attach a bit of extra boolean information to a value. It's important to become comfortable with them as they are used extensively throughout the F# libraries.

Have fun! Next we'll explore... well... I haven't decided yet. If you have any suggestions, feel free to email me at dustin AT diditwith.net.

1We'll explore discriminated unions in a future article.

posted on Monday, February 25, 2008 3:56:21 PM (Pacific Standard Time, UTC-08:00)  #    Comments [3]

kick it on DotNetKicks.com
 Thursday, February 21, 2008

Computer books

I don't know about you, but around my house, computer books have a habit of multiplying like rabbits. Sometimes it seems as if you can't put up your feet without resting them on a pile of old programming books. There are several reasons why these books proliferate so:

  • I like my shelves to reflect an intelligence that I don't actually possess.
  • I feel the need to own reference books that I never need to reference.
  • I purchase books on the latest and greatest technology before I realize that I'm not actually interested in said technology.
  • When I become interested in a topic, I tend to purchase every book ever written about it—even if a new book duplicates information I already have.
  • I buy classics that I have the best intentions of reading... but never do.
  • I acquire books for a specific project at work, and the project ends.

Because my shelves are bursting at the seams (and the Wife Acceptance Factor for them has become quite low), it's time for an early Spring cleaning. If you're interested in some reasonably-priced programming tomes, previously owned by a lesser-known blogger, feel free to browse my Amazon storefront.

(Quiz: How many of the books in above picture do you own?)

(Clarification: The books pictured above are not for sale. Those are keepers!)

posted on Thursday, February 21, 2008 12:44:48 PM (Pacific Standard Time, UTC-08:00)  #    Comments [17]

kick it on DotNetKicks.com
 Tuesday, February 19, 2008
Greetings fellow F#-philes! Today we're looking at another reason that I am completely infatuated with the F# language—pattern matching.

Pattern matching is a simple idea. Essentially, a pattern match takes an input and a set of rules. Each rule tests the input against a pattern and returns a result if they match.

The following naive implementation of the tired, old Fibonacci function shows simple pattern matching at work.

#light

let rec fib n =
  match n with
  | 0 -> 0
  | 1 -> 1
  | _ -> fib(n - 1) + fib(n - 2)

Pattern matching syntax is simple and clear. It should be readable by any programmer worth their salt. In fact, the above match .. with block is completely equivalent to the following C# switch statement:

static int Fib(int n)
{
  switch (n)
  {
    case 0:
      return 0;
    case 1:
      return 1;
    default:
      return Fib(n - 1) + Fib(n - 2);
  }
}

That's pretty unimpressive. I mean, if pattern matching were identical to standard switch statements, there really would be nothing exciting about them. Fortunately, there are some enormous differences that demote switch statements to a very distant cousin.

The first difference is subtle but profound: pattern matches return values. A pattern match is very much like a function that takes an argument and returns a value. Consider the following rewrite of our F# fib function:

#light

let rec fib n =
  let result = match n with
               | 0 -> 0
               | 1 -> 1
               | _ -> fib(n - 1) + fib(n - 2)
  result

The above example might be a bit contrived, but it illustrates the point. Simulating that with a switch statement is awkward.

static int Fib(int n)
{
  int result;
  switch (n)
  {
    case 0:
      result = 0;
      break;
    case 1:
      result = 1;
      break;
    default:
      result = Fib(n - 1) + Fib(n - 2);
      break;
  }
  return result;
}

Switch statements don't return values, so we can't assign a switch statement to a variable. Instead, we must use mutable state and pepper the cases with break statements. In essence, a pattern match is like a function while a switch statement is like a big GOTO.

In addition, pattern matching supports a wealth of features that truly set it apart from standard imperative switch statements.

Patterns can:

  1. Contain guard rules (e.g. match x but only when x is less than zero).
  2. Bind values to names.
  3. Decompose type structures.

Let's examine each of these in turn.

First, consider our original fib function with an additional pattern containing a guard rule:

#light

let rec fib n =
  match n with
  | _ when n < 0 -> failwith "value cannot be less than 0."
  | 0 -> 0
  | 1 -> 1
  | _ -> fib(n - 1) + fib(n - 2)

Now that's a bit more interesting! In C# or Visual Basic, we would have to introduce an if-statement at the beginning of the function to test for an invalid argument. In F#, the guard is inserted directly as a pattern rule.

Another indispensible feature of F# pattern matching is the ability to bind values to names.

So far, we've used the match .. with syntax to define pattern matches. This time, we'll use an alternative syntax that, although it is not required, easily demonstrates how values can be bound to names within pattern rules.

The alternative syntax can be used in the case where a function is defined with one argument and simply returns the result of a pattern match on that argument. In this syntax, the argument is not specified, and the keyword function is inserted. The match .. with statement needs to reference the argument name, but because the argument is unspecified, it has no name. Consequently, the match .. with statement must be removed, leaving us with a function that is defined entirely in terms of pattern matching rules. Because the argument is unnamed, values must be bound to names within the pattern rules.

A code sample is worth a thousand words.

#light

let rec fib = function
  | x when x < 0 -> failwith "value cannot be less than 0."
  | 0 | 1 as x -> x
  | x -> fib(x - 1) + fib(x - 2)

In the above code, we bind the name x in each pattern to make up for the fact that the argument is unspecified. In addition, the rules for 0 and 1 and have been combined using an "or" (or "union") pattern. Note that there are two different ways to bind a value to a name within a pattern rule. First, a name can simply be explicitly specified, substituted within the pattern. The other way is to use the as keyword. Both ways are demonstrated above.

The last feature of pattern matching that we'll look at is its capability to decompose type structures.

Recently, we saw that F# would automatically convert the result of Dictionary<TKey, TValue>.TryGetValue to a tuple if a variable isn't specified for the out parameter. In a comment to that article, Derek Slager presented a helper function that returns a default value if TryGetValue returns false. This helper function is an excellent practical example of a pattern match that decomposes a tuple value.

#light

open System.Collections.Generic

let getValueOrDefault (dict : #IDictionary<'a,'b>) key defaultValue =
  match dict.TryGetValue key with
  | true, value -> value
  | _ -> defaultValue

In addition to the tuple decomposition, the first rule elegantly binds the second part of the tuple to the name value. Sweet!

Because pattern matching is intrinsic to F# programming, we'll see more of it in upcoming articles. As features supporting pattern matching are introduced in this series, we'll build on the basics presented here.

Next up: the option type. See you then!

posted on Tuesday, February 19, 2008 7:39:00 AM (Pacific Standard Time, UTC-08:00)  #    Comments [5]

kick it on DotNetKicks.com