Friday, October 26, 2007
Lately, I've been spending some quality time with Microsoft's F# language. So far, I'm completely enamored with the brevity and clarity of the language. It just feels right to me.

I recently wrote up some articles on how one might use currying, partial application and function composition along with C# and delegates to produce the factorial function from two higher-order functions. The result of this labor is below.

static void Main()
{
  var reduce = HigherOrder.GetReduce<Int64>().Curry();
  var getProduct = reduce((x, y) => x * y)(1);

  var sequence = HigherOrder.GetSequence<Int64>().Curry();
  var naturalsFromOne = sequence(x => ++x)(1);

  var equals = HigherOrder.GetEquals<Int64>().Curry();

  var naturalsFromOneToX = HigherOrder.Compose(equals, naturalsFromOne);
  var factorial = HigherOrder.Compose(naturalsFromOneToX, getProduct);

  var factorialOf10 = factorial(10);

  Console.WriteLine("Factorial of 10 is {0:#,#}", factorialOf10);
}

That code is a truly magnificent beast. While it's academically interesting to torture delegates like this, it isn't all that fruitful when the language (i.e. C#, VB) doesn't really support these shenanigans. Try that in some production code and see how quickly you lose your development job.

As an exercise, here's how I might build factorial using the same techniques in F#:

#light

let getProduct = Seq.fold ( * ) 1
let naturalsFromOneToX n = [1 .. n]
let factorial = naturalsFromOneToX >> getProduct

printf "Factorial of 10 is %i" (factorial 10)

The first thing I should point out is that no delegates are used in this sample. F# natively supports functions as values so it's unnecessary to create delegates for them (and no, it doesn't create delegates under the covers). Secondly, functions are automatically curried in F#. You can declare functions so that they aren't curried, but that's really only useful if you're writing code that should be callable from other .NET languages. And finally, F# provides an operator (>>) for function composition.

To be fair, I should point out that the above implementation is pretty naive. It's not necessary to use function composition. This will suffice:

#light

let factorial n = Seq.fold ( * ) 1 [1 .. n]

printf "Factorial of 10 is %i" (factorial 10)

If compiled with fsc.exe, that code will print the following to the console:

Factorial of 10 is 3628800

That's great, but what if I try to calculate the factorial of 1000?

Factorial of 1000 is 0

Hmmm... what's going on here? Well, it turns out that the F# compiler inferred the type of "factorial" to be:

val factorial : int -> int

"int" maps to the standard .NET type, System.Int32, so this factorial function expects an Int32 and returns an Int32. However, Int32 isn't actually large enough to hold the factorial of 1000. This is a job for F#'s "bigint" type. "bigint" maps to the Microsoft.FSharp.Math.Types.BigInt type which can represent arbitrarily large integer values. With a few minor modifications, the factorial function can use "bigint," and the factorial of 1000 can be properly calculated.

#light

let factorial n = Seq.fold ( * ) 1I [1I .. n]

printf "Factorial of 1000 is %A" (factorial 1000I)

Now, the F# compiler infers the type of "factorial" to be:

val factorial : bigint -> bigint

And what does that program print to the console?

Factorial of 1000 is 40238726007709377354370243392300398571937486421071463254379
99104299385123986290205920442084869694048004799886101971960586316668729948085589
01323829669944590997424504087073759918823627727188732519779505950995276120874975
46249704360141827809464649629105639388743788648733711918104582578364784997701247
66328898359557354325131853239584630755574091142624174743493475534286465766116677
97396668820291207379143853719588249808126867838374559731746136085379534524221586
59320192809087829730843139284440328123155861103697680135730421616874760967587134
83120254785893207671691324484262361314125087802080002616831510273418279777047846
35868170164365024153691398281264810213092761244896359928705114964975419909342221
56683257208082133318611681155361583654698404670897560290095053761647584772842188
96796462449451607653534081989013854424879849599533191017233555566021394503997362
80750137837615307127761926849034352625200015888535147331611702103968175921510907
78801939317811419454525722386554146106289218796022383897147608850627686296714667
46975629112340824392081601537808898939645182632436716167621791689097799119037540
31274622289988005195444414282012187361745992642956581746628302955570299024324153
18161721046583203678690611726015878352075151628422554026517048330422614397428693
30616908979684825901254583271682264580665267699586526822728070757813918581788896
52208164348344825993266043367660176999612831860788386150279465955131156552036093
98818061213855860030143569452722420634463179746059468257310379008402443243846565
72450144028218852524709351906209290231364932734975655139587205596542287497740114
13346962715422845862377387538230483865688976461927383814900140767310446640259899
49022222176590433990188601856652648506179970235619389701786004081188972991831102
11712298459016419210688843871218556461249607987229085192968193723886426148396573
82291123125024186649353143970137428531926649875337218940694281434118520158014123
34482801505139969429015348307764456909907315243327828826986460278986432113908350
62170950025973898635542771967428222487575867657523442202075736305694988250879689
28162753848863396909959826280956121450994871701244516461260379029309120889086942
02851064018215439945715680594187274899809425474217358240106367740459574178516082
92301353580818400969963725242305608559037006242712434169090041536901059339838357
77939410970027753472000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000I

Awesome.

One last point: writing factorial in F# is completely unnecessary. It already exists.

#light

open Microsoft.FSharp.Math.BigInt

printf "Factorial of 1000 is %A" (factorial 1000I)
posted on Friday, October 26, 2007 3:02:36 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
 Thursday, October 25, 2007
Back in June, Scott Hanselman and Jeff Atwood embarked on a journey to create the "Ultimate Developer Rig." I followed this with interest because I currently use a laptop for development. The laptop is convenient because I do a reasonable amount of traveling. However, recently I've found myself craving something with more horsepower and am giving serious consideration to moving my main development to a desktop and syncing the laptop for travel.

Without consulting my trophy wife, I decided to check out NewEgg to see what the components of the Ultimate Developer Rig are down to, price-wise. Here's what I found:

Component Old Price New Price
Antec P182 Gun Metal Black 0.8mm cold rolled steel ATX Mid Tower Computer Case - Retail $154.99 $139.99
MSI P6N SLI Platinum LGA 775 NVIDIA nForce 650i SLI ATX Intel Motherboard - Retail $144.99 $139.99
MSI NX8600GTS-T2D256E-OC GeForce 8600GTS 256MB 128-bit GDDR3 PCI Express x16 HDCP Ready SLI Supported Video Card - Retail $337.98 $299.98
Western Digital Raptor WD1500ADFD 150GB 10,000 RPM Serial ATA150 Hard Drive - OEM $199.99 $179.99
Seagate Barracuda 7200.10 ST3500630AS 500GB 7200 RPM SATA 3.0Gb/s Hard Drive - OEM $119.99 $119.99
Intel Core 2 Quad Q6600 Kentsfield 2.4GHz LGA 775 Processor Model BX80562Q6600 - Retail $531.90 $279.99
Scythe SCMN-1100 100mm Sleeve CPU Cooler - Retail $32.99 $32.99
CORSAIR CMPSU-520HX ATX12V v2.2 and EPS12V 2.91 520W Power Supply - Retail $129.99 $119.99
Kingston ValueRAM 2GB (2 x 1GB) 240-Pin DDR2 SDRAM DDR2 800 (PC2 6400) Dual Channel Kit Desktop Memory Model KVR800D2N5K2/2G - Retail $216.98 $157.98
LITE-ON 20X DVD±R DVD Burner with 12X DVD-RAM write and LightScribe Technology Black E-IDE/ATAPI Model LH-20A1H-185 - OEM $33.99 $32.99
  $1,903.79 $1,503.88

I'm absolutely blown away. I mean, we're talking about a price difference of nearly $400. That leaves room for a few choice upgrades like moving to 8GB of ram. All that I have to do now is get my trophy wife to sign off on it.

posted on Thursday, October 25, 2007 12:52:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [5]

kick it on DotNetKicks.com
 Wednesday, October 24, 2007
Today, I got an email from Keith Elder calling me out for not being on Twitter:
FYI, you are no longer cool :)

Email from Elder

Normally, I would swim through boiling lava to remain among "the cool" (even if only in my own mind), but it didn't come to that. Signing up was mind-numbingly easy. Follow me: dcampbell.

Thanks to The Elder and The Follas for keeping me cool.

posted on Wednesday, October 24, 2007 2:33:43 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Tuesday, October 23, 2007
The biggest danger of working with my boss is, quite frankly, jealousy. Don't misunderstand me. It's not jealousy of his considerable programming chops or his modest good looks. It's his wide range of stalkers that evokes my pangs of envy. Nothing defines fame quite as definitively as the number and variety of one's stalkers.

Over the past years, I've declared a few people to be "my stalker."

First, there was Jason Follas because of his stalker-ish way of chasing me down to speak at the Northwest Ohio .NET User Group. Here are some choice quotes:

"First off, I'm still floored by the fact that a CodeRush/Refactor developer lives this close to me..."

"Even though you probably haven't read the first email yet, I was wondering if you might be available and willing to speak at the user group meeting next Tuesday..."

Jason showed a lot of promise, but his heart really isn't in it. This quote from his very first email to me clarifies his level of commitment as a stalker:

"Anyways, your name doesn't sound familiar to me, so I hope that we haven't met before."

Oh yeah! Can you feel the love?

Then of course, there was Jeff McWherter. Jeff approached me this year at Tech Ed to discuss a talk that I had given a month earlier over a 1,000 miles away. Truthfully, Jeff was just being conversational, but I jumped all over his pleasantries with cries of, "Ha! You're my stalker now buddy!" Lately, I've been questioning how seriously Jeff has been taking his roll as a stalker. Recent encounters have involved him darting around corners while I shout, "HEY! Aren't you going to stalk me!? Why aren't you going through my trash or taking distant, blurry photos of me?"

I guess that I've just been trying too hard.

Until today.

Finally, I have real stalker of my very own: Dan Hounshell. That's right Dan. I read your blog, and I saw your post.

Dan Hounshell

After seeing this photo, I'll be sleeping with one eye open.

A stalker of my very own.

I've finally arrived.

posted on Tuesday, October 23, 2007 2:31:30 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
In the seventh article of my series on functional programming ideas using C#, I build on the ideas of currying and partial application. In addition, I cover a new concept: function composition.
posted on Tuesday, October 23, 2007 9:43:45 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Monday, October 15, 2007
I'm giving some talks in the Ohio/Michigan area over the next week.

If you're in the area, stop by. We'll enjoy a frosty beverage afterwards. :-)

posted on Monday, October 15, 2007 12:36:31 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
 Thursday, October 11, 2007
Last night, I happened upon an episode of the Sci-Fi Channel's "Ghost Hunters" and was struck by the uncanny resemblance between lead investigator Jason Hawes and my good friend Josh Holmes.

Jason HawesJosh Holmes

Clearly, Josh is getting a bit more sun than Jason, but the likeness is striking. At least, as striking as the resemblance between two goatee-wearing, head-shaving men can be. Were they separated at birth? Hmmm...

posted on Thursday, October 11, 2007 10:19:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Friday, September 28, 2007

Recently, I presented an example of how closures can cause headaches when used in the context of LINQ expressions:

static class Program
{
  static void Main()
  {
    var filter = String.Empty;
 
    var query = from m in typeof(String).GetMethods()
                orderby m.Name
                where m.Name != filter
                select m.Name;
 
    foreach (var item in query)
    {
      Console.WriteLine(item);
      filter = item;
    }
  }
}

I want to state clearly that the example above is academic and not representative of how anybody should be writing LINQ code. This was implied by the intentionally-alarmist title of my post ("LINQ Closures May Be Hazardous to Your Health!"), but some readers missed the point. Let's take a closer look at what, exactly, is wrong with this LINQ code and how it should be properly written.

First of all, the example code exhibits several nasty smells:

  1. It isn't portable. There's no guarantee that other LINQ providers will actually support closures.
  2. It isn't maintainable. The code is an obvious maintenance headache—especially if it will be handled by more than one person.
  3. It isn't declarative. LINQ syntax is designed to be declarative, but this code mixes in imperative logic.
  4. It isn't flexible. The closure voodoo inhibits potential optimizations that might occur with future technologies like Parallel LINQ.

In addition to the negative consequences listed above, the closure exploited in the sample is completely unnecessary! Closures can sometimes be powerful, but this isn't really the place to exploit them. In fact, writing code like that betrays a lack of knowledge of LINQ's standard query operators. LINQ already provides an easy way to ensure that duplicate values are removed from a query expression: the Distinct operator.

Distinct is one of several query operators designed to perform set operations on queries (the other operators are Except, Intersect and Union). Using Distinct in place of the closure solves all of the afore-mentioned problems and, as a bonus, makes the code more concise.

static void Main()
{
  var query = (from m in typeof(String).GetMethods()
              orderby m.Name
              select m.Name).Distinct();
 
  foreach (var item in query)
    Console.WriteLine(item);
}

Not surprisingly, Visual Basic takes this a step further by adding a new "Distinct" keyword.

Sub Main()
  Dim query = From m In GetType(String).GetMethods() _
              Order By m.Name _
              Select m.Name _
              Distinct
 
  For Each item In query
    Console.WriteLine(item)
  Next
End Sub

However, this new keyword only gives me a mild case of VB Envy. I really like the fact that Distinct is syntax highlighted, but I much prefer how the parentheses better delineate the query expression in the C# version.

I hope this clears up any confusion that my other post might have caused. LINQ syntax is designed to be simply and declarative. Don't let your code get too fancy, and you'll reap the benefits of LINQ.

posted on Friday, September 28, 2007 12:47:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Tuesday, September 25, 2007
Jomo Fisher is a C# team member who works on LINQ to SQL. Recently, Jomo has been exploring F# by compiling bits of code and seeing what the F# compiler generates. So far, I've found this "Adventures in F#" series to be quite enjoyable, and I recommend it to any interested readers. Here is a list of the articles posted to date:
I should point out that this series is not an introduction to functional programming or F#. Instead, it is more technical in nature and asks the question, "How does the compiler do that?"
posted on Tuesday, September 25, 2007 10:54:10 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
UPDATE (Sep. 28, 2007): This article is really academic in nature on the topic of closures and how they fit into LINQ query expressions. It contains a highly-contrived example that is not representative of quality LINQ code. For more information, take a look at this post.

To me, one of the most interesting aspects of LINQ query expressions is that they produce lexical closures (for a detailed look at closures in C#, see my article on the topic). To illustrate this point, consider the following code:

static void Main()
{
  var filter = "Compare";
 
  var query = from m in typeof(String).GetMethods()
              where m.Name.Contains(filter)
              select new { m.Name, ParameterCount = m.GetParameters().Length };
 
  foreach (var item in query)
    Console.WriteLine(item);
 
  Console.WriteLine();
  Console.WriteLine("--- press any key to continue ---");
  Console.ReadKey();
}

This query retrieves all of the public methods on System.String whose names contain the text represented by the "filter" variable (in this case "Compare"). When compiled and run, the output is what you might guess:

{ Name = Compare, ParameterCount = 2 }
{ Name = Compare, ParameterCount = 3 }
{ Name = Compare, ParameterCount = 3 }
{ Name = Compare, ParameterCount = 4 }
{ Name = Compare, ParameterCount = 5 }
{ Name = Compare, ParameterCount = 6 }
{ Name = Compare, ParameterCount = 7 }
{ Name = Compare, ParameterCount = 6 }
{ Name = CompareTo, ParameterCount = 1 }
{ Name = CompareTo, ParameterCount = 1 }
{ Name = CompareOrdinal, ParameterCount = 2 }
{ Name = CompareOrdinal, ParameterCount = 5 }

--- press any key to continue ---

That behavior should be perfectly natural to any C# developer. Here's where things get a little tricky:

var filter = "Compare";

var query = from m in typeof(String).GetMethods()
            where m.Name.Contains(filter)
            select new { m.Name, ParameterCount = m.GetParameters().Length };

filter = "IndexOf";

foreach (var item in query)
  Console.WriteLine(item);

Can you guess what that code will output to the console?

Your answer to that question depends on your understanding of what closures are and how they work. A closure is produced when a variable whose scope extends beyond the current lexical block is bound to that block. That's a bit of a mouthful, isn't it? Allow me to clarify what I mean with a simple example.

delegate void Action();
 
static void Main()
{
  int x = 0;
 
  Action a = delegate { Console.WriteLine(x); };
 
  x = 1;
 
  a();
}

In the code above, an anonymous delegate ("a") references a variable ("x") that is declared outside of the anonymous delegate's body. This implies a lexical closure, and the variable "x" is bound to the method body of "a." The important point is that "a" is bound to the variable "x" and not its value. In other words, the value that "a" writes to the console depends upon the value of "x" at the time of its execution. Because 1 is assigned to "x" immediately before "a" is executed, 1 is output to the console.

Precisely the same thing happens in our query expression. A closure is produced for the lambda expression of the "where" clause because it references the "filter" variable, which is declared outside of the query expression. The closure binds to the variable "filter"—not its value. So, changing the value of "filter" after the query expression is defined will change the results returned by the query. In fact, if you run that code, you'll get this:

{ Name = IndexOf, ParameterCount = 3 }
{ Name = IndexOfAny, ParameterCount = 3 }
{ Name = LastIndexOf, ParameterCount = 3 }
{ Name = LastIndexOfAny, ParameterCount = 3 }
{ Name = IndexOf, ParameterCount = 1 }
{ Name = IndexOf, ParameterCount = 2 }
{ Name = IndexOfAny, ParameterCount = 1 }
{ Name = IndexOfAny, ParameterCount = 2 }
{ Name = IndexOf, ParameterCount = 1 }
{ Name = IndexOf, ParameterCount = 2 }
{ Name = IndexOf, ParameterCount = 3 }
{ Name = IndexOf, ParameterCount = 2 }
{ Name = IndexOf, ParameterCount = 3 }
{ Name = IndexOf, ParameterCount = 4 }
{ Name = LastIndexOf, ParameterCount = 1 }
{ Name = LastIndexOf, ParameterCount = 2 }
{ Name = LastIndexOfAny, ParameterCount = 1 }
{ Name = LastIndexOfAny, ParameterCount = 2 }
{ Name = LastIndexOf, ParameterCount = 1 }
{ Name = LastIndexOf, ParameterCount = 2 }
{ Name = LastIndexOf, ParameterCount = 3 }
{ Name = LastIndexOf, ParameterCount = 2 }
{ Name = LastIndexOf, ParameterCount = 3 }
{ Name = LastIndexOf, ParameterCount = 4 }

--- press any key to continue ---

Let's try to exploit this closure in a more practical way.

var filter = String.Empty;

var query = from m in typeof(String).GetMethods()
            where m.Name != filter
            select m.Name;

foreach (var item in query)
{
  Console.WriteLine(item);
  filter = item;
}

This slightly different query expression returns the names of all of the public methods on System.String that don't match the value of the variable "filter." By modifying "filter" in each iteration of the foreach loop, we are effectively filtering out all duplicate method names. This works as advertised, but there's one potential bug: it is assumed that all overloads of a method are grouped together. If there are overloads of, say, String.CompareTo that aren't adjacent in the source array, the filtering won't work properly. What we really need to do is sort the array using the "orderby" query operator.

var query = from m in typeof(String).GetMethods()
            where m.Name != filter
            orderby m.Name
            select m.Name;

WHOOPS! That doesn't work. When we execute that query, all of the method names are output to the console, including duplicates. Our modifications to the "filter" variable in the foreach loop are completely ignored. Why is that?

The reason is that "orderby" forces the entire query to be evaluated when the first element is requested. This behavior is unavoidable and breaks the normal delayed evaluation of a query expression. However, we can still make the closure work properly by ensuring that the sort happens before filtering.

var query = from m in typeof(String).GetMethods()
            orderby m.Name
            where m.Name != filter
            select m.Name;

Now we get the output that we want:

Clone
Compare
CompareOrdinal
CompareTo
Concat
Contains
Copy
CopyTo
EndsWith
Equals
Format
get_Chars
get_Length
GetEnumerator
GetHashCode
GetType
GetTypeCode
IndexOf
IndexOfAny
Insert
Intern
IsInterned
IsNormalized
IsNullOrEmpty
Join
LastIndexOf
LastIndexOfAny
Normalize
op_Equality
op_Inequality
PadLeft
PadRight
Remove
Replace
Split
StartsWith
Substring
ToCharArray
ToLower
ToLowerInvariant
ToString
ToUpper
ToUpperInvariant
Trim
TrimEnd
TrimStart

--- press any key to continue ---

The moral here is to be careful. Exploiting closures in query expressions can be powerful but tricky to get right.

posted on Tuesday, September 25, 2007 9:53:23 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com