Saturday, March 29, 2008

Website Performance Talk

This is a really enlightening talk from Steve Souders, author of High Performance Websites, and Chief Performance Yahoo!.  Below is a summary of his talk, but they also have a page detailing their rules.

  1. Make fewer HTTP requests: combing CSS and Javascript files, CSS sprites*, use image maps instead of multiple images where possible, inline images*
  2. Use a Content Distribution Network.  Akamai, Panther Express, Limelight, Mirror Image, SAVVIS.  Distribute your static content before creating a distributed architecture for your dynamic content.
  3. Add an Expires header.  If you aren't already, you should be changing the URL of your resources when you version them, to ensure that all users will get updates and fixes.  Since you then won't be updating a given resource, you should give it a far future expires header.
  4. Gzip all content: html, css, and javascript.
  5. Put stylesheets at the top.  IE will not begin rendering until all CSS files are downloaded.  Use the link HTML tag to pull in stylesheets, not the @import CSS directive, as IE will defer the download of the stylesheet.
  6. Put javascripts at the bottom.  HTTP 1.1 allows for two parallel server connections per hostname, but all downloads are blocked until the script is downloaded.  The defer attribute of the script block is not supported in Firefox and doesn't really defer in IE.
  7. Avoid CSS expressions.  The speaker doesn't cover this, but I gather from my own experience that this can seriously delay rendering as the expression will not be evaluated until the page is fully loaded.
  8. Make CSS and JS external.  This rule can be bent in situations where page views are low and users don't revisit often.  In this situation in-lining is suggested.
  9. Reduce DNS lookups.  He didn't cover this either, but it follows from rule #1 that additional network requests negatively impact performance.  He does mention later in the talk that splitting your requests across domains can drastically increase response time.  This is a consequence of the two connections per domain limit in the HTTP 1.1 specification.  It is important to remember that JavaScripts from one domain cannot affect JavaScripts or pages from another domain, due to browser security restrictions.  Also, this is a case of diminishing returns, as beyond four domains causes negative returns from, presumably DNS lookups and resource contention in the browser itself.
  10. "Minify" Javascript.  JSMin written by Doug Crockford is the most popular tool.  This is just removing whitespace, generally.  YUI compressor may be preferred and also does CSS.
  11. Avoid redirects.
  12. Remove duplicate scripts.
  13. Configure ETags.  These are used to uniquely identify a resource in space and time, such that if the ETag header received is identical to the cached result from a previous request for that resource, the browser can choose to use the local cache without need to download the remainder of the response stream.  The speaker doesn't go into this subject, so questions about how this improves caching performance over caching headers remain unanswered until you read his book.
  14. Make AJAX cacheable.  If you embed a last modified token into the URL of your AJAX request, you can cause the browser to pull from cache when possible.

A great tool to analyze your site's conformance to these rules is YSlow.  It's an add-on for Firebug.  During development your YSlow grade can give you a very good indication of what is happening to the response time of your application.  This metric, the YSlow grade, seems to me to be a much better quality gate for iterative development than does something as variable and volatile measured response time.

Some additional rules from the next version of the book:

  • As mentioned in my commentary in rule #9, split dominant content domains.
  • Reduce cookie weight.
  • Make static content cookie free.
  • Minify CSS (see rule #10 comments above).
  • Use iframes wisely.  The are a very expensive DOM operation.  Think about it--it's an entirely new page, but linked to another.
  • Optimize images.  Should your GIFs be PNGs?  Should your PNGs be JPGs?  Can you shrink your color palette?

Wednesday, March 19, 2008

Erlang News

Robert Virding's First Rule: "Any sufficiently complicated concurrent program in another language contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Erlang."

"I now know based on hard-won experience that you could replace "concurrent program" with "distributed system" in Robert's rule and it would still be just as accurate." --Steve Vinosky

Yariv wrote a cogent response to "What Sucks About Erlang".

Erlang Flavored Lisp anyone?

Monday, March 10, 2008

Programming Erlang: Chapter 8 Problem 2

'Tis an odd title, I know.  My puppy is prancing around the kitchen trying to get me interested in his chew toy, dropping it near me so I can see that it bounces and wiggles.

Do you want to see Erlang bounce and wiggle? The code below creates a circular linked list of Erlang N processes, then sends a Message around it M times. Pretty cool, huh? Well, it was meant to be used by readers of "Programming Erlang" to compare their favorite language to Erlang. I didn't bother doing this with C# threads, though it would be interesting to try it out with the concurrency and co-ordination runtime.

Here's the out put of the code (time is in milliseconds):

Sent 30000000 messages in 27453 / 29186


-module(problem2).
-compile(export_all).

start(N, M, Message) when is_integer(N), is_integer(M) ->
statistics(runtime),
statistics(wall_clock),
FirstPid = spawn(?MODULE,loop,[[]]),
LastPid = create(1, N, FirstPid),
FirstPid ! LastPid, %% the ring is closed
send(0, M, FirstPid, Message),
{_, Time1} = statistics(runtime),
{_, Time2} = statistics(wall_clock),
io:format("Sent ~p messages in ~p / ~p~n", [N * M, Time1, Time2]).

send(C, C, _Pid, _Message) -> void;
send(I, C, Pid, Message) ->
Pid ! {self(), Message},
receive
finished -> void
end,
send(I+1, C, Pid, Message).

create(C, C, Pid) -> Pid;
create(I, C, Pid) ->
create(I+1, C, spawn(?MODULE, loop, [Pid])).

loop(Next) ->
receive
{Caller, FirstPid, Message} ->
if
FirstPid =:= self() -> Caller ! finished;
true -> Next ! {Caller, FirstPid, Message}
end,
loop(Next);
{Caller, Message} ->
Next ! {Caller, self(), Message},
loop(Next);
NewNext when Next =:= [] ->
loop(NewNext)
end.

Friday, February 15, 2008

Presenter First with POA

Plain-old ASP.NET (POA) has a lot of advantages: rapid UI prototyping, incomparable support from 3rd-party vendors, and a simplified programming model that abstracts away the problems of a stateless application to name a few.  But there remains the problem of testing.  ASP.NET applications--any web-based application--is difficult to test.  The traditional architecture of having your code-behind orchestrate your business logic components in response to events generated through the postback mechanism requires that you instigate those postbacks in order to test the orchestration.  In other words, you have to drive the UI to test your application.

UI testing is expensive.  If you've done it, you already know that.  If you've not done it, then trust us on this one; the cost of tools, the complexity, and brittleness of web tests drive the cost up.  Furthermore, if an application isn't designed to be UI tested, it becomes a nearly intractable problem to do so.  The folks at Atomic Object know this from experience.  As proponents of test-driven development, they have looked down the barrel of that gun and found a better way.  They call it Presenter First.

The basic idea behind Presenter First (PF) is to obviate the need for UI testing.  It is a Model-View-Presenter (MVP) variant that is closely related to Martin Fowler's Passive View.  The application architecture is such that UI is so humble that there is no need to test the UI.  This architecture requires that the Presenter be responsible for orchestrating the Model (business components) in response to events generated by the View, and updating the View appropriately.  A View in PF only implements events and property set methods.  This View can be defined by contract, e.g. IView, and mocked to allow for test-driven development. 

A hallmark of PF is that Presenters are constructed with an IView and an IModel and do not implement any other public interface members.  Thus, the encapsulated worfklow is driven completely through IView and (possibly) IModel events.  Concordantly, it becomes evident that PF architectures are implicitly stateful, i.e. the Presenter is extant between events.  In POA, the HttpContext only exists for the duration of the processing of a request.  While the HttpSession remains there is a non-trivial amount of complexity involved with it; ultimately, this too should be considered transient in the general case.  From these facts one might conclude that PF is not applicable to POA.

The purpose of this writing is to propose a method of implementing Presenter First in ASP.NET.  The general approach is outlined below:

  1. All page's implementing a PF IView (e.g. ICustomerEditView) must inherit from PFPage.
  2. PFPage implements a Dictionary<typeof(IView),PresenterInstance> lookup.
  3. Before Page processing, the PresenterInstance is given a reference to the View, i.e. the current page.
  4. The IView events are fired (from postback) and the Presenter handles them appropriately, updating the View via setters.
  5. The Presenter handles the Page.Unload event and drops its View reference

This approach diverges from "classical" PF in a few ways.  Most importantly, the actual concrete View acted upon by the Presenter instance is transient.  This should not pose any particular difficulty as the ASP.NET postback model ameliorates this stateless condition of web applications.  Further, while this requires the Presenter interface to implement a mutator for its View reference, the Presenter implementation need not diverge from the "classical" PF approach, save in one important way.  IModel events would need to be queued.[1]

Furthermore, the Presenter instance and the dictionary must be serializable if that pattern is to be used in an ASP.NET deployment where the HttpSession was out-of-process.  This might propose problems with Presenter references to cached objects that can't be extended to support serialization; though this is considered a minor flaw in the general case and an impediment that can be ameliorated by recreating objects from metadata.

To compose views it would only be necessary to create a PFControl base class that implemented nearly identical functionality to the PFPage.  Also, though declarative databinding is no longer possible, DTOs could be used in View mutators for databinding.

Through the use of mock objects, this approach to ASP.NET development using Presenter First enables Test-Driven Development of the business objects and their orchestration in response UI events to without the need to involve ASP.NET pages.[2]  Additionally, this allows for the tandem of presentation (.aspx) and interaction (.aspx.cs) to be isolated from business logic (Model) and orchestration (Presenter).

Please let me know what you think.  Is your organization using a very similar approach?  How have you fared?

[1] Because the Presenter MUST NOT call mutator methods on the View between postbacks, IModel events must be queued until a new View instance is received.

[2] While issues such as declarative security and AJAX can make UI testing a necessity, we are assuming that these are not direct considerations for vetting the business logic and orchestration.  Further this kind of UI testing will generally be done as a part of UAT and thus does not "cost" the development team.

Tuesday, February 12, 2008

Upgrading to Windows Vista

There's a certain voodoo to searching for problems. I don't expect that anyone is actually going to read this before upgrading to Vista... but here are the three problems I had.

First, make sure if you are running DaemonTools that you uninstall it first.  The Vista upgrade will force you to do this before proceeding, but sptd.sys will not be removed.  So... remove it.  It's in your Windows directory.

Next, make sure you download Vista updates for all your drivers.  I couldn't get my external monitor for my laptop to use it's native resolution.  The generic monitor driver in Vista didn't allow it.  I went to my manufacturer's website, NEC's, and download Vista drivers for the monitor.

Lastly (I hope), you might have trouble connecting to a cheaper broadband router.  Well, you'll be able to connect, but you won't get a DHCP address.  This knowledge base article should do the trick.

So, what do I think of Vista...?

I guess I don't know what all the hullabaloo has been about in the blogs and press.  Surely no one was expecting Mac OSX?  I run Ubuntu Linux too, and I don't expect it to be OSX.  In fact, I think Ubuntu's desktop experience sucks compared to Vista, but I love it as a Linux distro.  I ran Slackware in '98, and I can tell you things have REALLY changed in ten years.  And, I can tell you Vista is better than XP.  You have to take that with a grain of salt; I relish change.

Sure, you will have more trouble pirating music, but it's more secure, prettier, and cooler.

I guess that's why Vista is making Microsoft money.  Go figure.

Sunday, February 3, 2008

Weekend Update with Christopher Atkins

Dennis Miller was my favorite Weekend Update anchorman.  His wry, sardonic--if verbose--commentaries always made me laugh.  As I think about it, that sketch seems a direct ancestor of the news shows on Comedy Central so popular with the college crowd.

Anyway, my weekend has been interesting.  I found out that despite what the documentation says, ECDiffieHellmanCng is not supported on Windows XP.  In fact, its constructors check for the presence of NCrypt.dll: a library only available for Windows Vista and Windows Server 2003+.  So, despite that fact that it ships with .NET 3.5, you can't use it on XP.  Joy.  I hope this is not a trend.  You'll also find that you cannot use a BigInt, because it is marked internal.  If you're trying to do modern cryptography on Windows XP, in other words, you are out of luck.

So, I spent the remainder of my weekend working through Programming Erlang, and I have to say I am even more excited about it.  I'm only on page 51, but I've already learned about list comprehensions and custom flow control abstractions using higher-order functions.  The cool thing is I can apply some of this stuff to C#, now that we have lambda expressions.

I'm excited about the year ahead.  There are a lot of changes on the horizon.  Imagine, Windows Server 2008, SQL Server 2008, a Yahoo! and Microsoft merger, widespread adoption of OpenID, and a new presidential election are all on their way.  To quote the folk poet Bob Dylan:

Come writers and critics
Who prophesize with your pen
And keep your eyes wide
The chance won't come again
And don't speak too soon
For the wheel's still in spin
And there's no tellin' who
That it's namin'.
For the loser now
Will be later to win
For the times they are a-changin'

Wednesday, January 30, 2008

Competence != Compensation

In America we are conditioned to believe that working hard, being diligent, and producing great work is the road to fiscal success.  Anyone who has really worked here will tell you that is simply not the case.  Prima facie, you must recognize that you are not paid what you are "worth"; that is, your personal worth has nothing to do with your income.  One must never forget this simple fact.  Despite the fact that you may do three times the work of your peers, you will not be compensated even twice as much.

Witness the Home Depot CEO who purposefully runs his stock in the ground, knowing well that a golden parachute awaits for him once the board of directors requests that he "step down."  Negative output results in a cash payout worth over $200 million dollars.  In America, you are worth what someone will pay you.  There is no such thing as intrinsic value, only assessed value.  In software development there are two ways of having your value assessed, by managers and by investors.

Make sure you don't hang your hopes on managers.

Continuous Integration with TFS: Pre-compiling a Web Application Project

If you are looking to pre-compile your web application projects with TFS 2008 Team Build, here are some tips.

First, you'll want to add the following to your TFSBuild.proj:

<Target Name="AfterDropBuild">
<
AspNetCompiler
PhysicalPath="$(DropLocation)\$(BuildNumber)\Release\_PublishedWebsites\web_project_name"
Debug="false"
Force="true"
TargetPath="C:\path_to_copy_precompiled_web_to"
VirtualPath="/Path_to_your_web"
/>
</
Target>


There a few things to note here.  First, the Target Name is crucial; this Target will get executed after the drop is made, i.e. after the build successfully runs and your files are copied to the drop folder you specified when you created the build.  Secondly, remember that this is running from the machine where your build agent runs.  The AspNetCompiler MSBuild tag shown here will launch aspnet_compiler.exe on that build agent machine, and so "/Path_to_your_web" points to the virtual directory on the default web site of your build agent machine.  Please note that "/Path_to_your_web" would be "/" in the case of your application being in the root directory.  Finally, the Force parameter is required since we will be writing over the existing pre-compiled web on subsequent builds.



If you want setup a build agent on another machine, perhaps a development web server where you would prefer to deploy the pre-compiled web application, you'll need to configure that agent according to these instructions.  This is a good idea when running verification tests that drive the web UI.



Happy Coding!

Saturday, January 26, 2008

On a Positive Note

Jean-Paul Boodhoo is a developer and consultant who used to work at ThoughtWorks and has been featured on the Polymorphic Podcast and DNRtv.  He recently posted a very encouraging post about dreams, risk, and reward.

Here's an excerpt.

I was speaking with a friend yesterday who made an interesting comment:

“You seem to regularly take on more stress than most other people would ever think to take on”

I corrected him and made this statement. I don’t feel like I am stressed out that much. In all honesty, the times that I feel stressed out almost always constitute a failure to plan on my part. I did say that what I do take on regularly is: Challenge and Risk. I am not afraid of the opportunity to fall flat on my face taking a risk, because I now that it is in the times of struggle/pain that growth happens.

Bravo.  That's well said.  Paul Graham (all your Lisp are belong to us) wrote a year ago explaining: How to Do What You Love.  Here's a quote, emphasis added:

Once, when I was about 9 or 10, my father told me I could be whatever I wanted when I grew up, so long as I enjoyed it. I remember that precisely because it seemed so anomalous. It was like being told to use dry water. Whatever I thought he meant, I didn't think he meant work could literally be fun—fun like playing. It took me years to grasp that.

Sure, sure, I heard you saying... do what you love, right?  Well, I love vacations, the ocean, playing guitar, and chasing my puppy--how do I get paid to do that?  The truth is you don't; you won't; and you shouldn't.  Again, from Mr. Graham:

Unproductive pleasures pall eventually. After a while you get tired of lying on the beach. If you want to stay happy, you have to do something.

I can't tell you how invigorating working in the yard can be or how exciting solving some mildly difficult programming problem can be.  It's enough to make people blog about their experiences.  But, even these are just short-term examples, what is it that you would love to do over the long haul?  Is there some sort of heuristic that we can apply to help use decide?  Here's Graham's idea:

I think the best test is one Gino Lee taught me: to try to do things that would make your friends say wow.

If you hate what you do, I cannot convince you that trying to impress your friends with it is going to make it fun.  So, think of the things you do that you do try to impress your friends with?  Do you love to cook?  Master the art, learn the language, hone your technique, and blog about the experience.  Start a in-home cooking class consultancy.  Do you love to take photographs?  Practice, learn, take your camera everywhere, make it your first thought.  Do you love it enough to do it for free?

The test of whether people love what they do is whether they'd do it even if they weren't paid for it—even if they had to work at another job to make a living. How many corporate lawyers would do their current work if they had to do it for free, in their spare time, and take day jobs as waiters to support themselves?

If you don't have enough passion to work hard at something and get better, then you either don't love it or you don't have an audience.  You might just need new friends.  Seek them out in classes or online discussion groups.  But seek them out.

If you are worried about money, if you're worried about being responsible for the well-being of your children or spouse, remember that you have a responsibility to them.  You are responsible for loving them, for inspiring them, for trying to be the best person you can for them.  Those are your true responsibilities; you can find a way to pay the really important bills.  Don't let fear admit apathy.  Don't use your family as an excuse.

If you don't already know what you love to do--and so few of us really do--Graham has further advice:

It's hard to find work you love; it must be, if so few do. So don't underestimate this task. And don't feel bad if you haven't succeeded yet. In fact, if you admit to yourself that you're discontented, you're a step ahead of most people, who are still in denial. [..] Finding great work you love does usually require discipline.  Is there some test you can use to keep yourself honest? One is to try to do a good job at whatever you're doing, even if you don't like it. [...] Another test you can use is: always produce.

If you are telling yourself that you hate your day job, and one day you will be set free to do what you love, then you better being doing what you love and consistently.  Otherwise, you're lying to yourself and everyone around you.  The hardest thing to admit is that at age 20, 30, 40, or 50 is that you don't know what you love; you don't know what you want to do when you grow up.  My point here is that you must do something; you must produce.  Even if you prove to be rather amateurish in all you attempt, but you really gave it your best, you will be happier--and much more interesting.  The worst thing you can be in your work-life, truly, is be a dilettante.

I will close by leaving you with these further words from Graham's essay (please read it):

"Always produce" is also a heuristic for finding the work you love. If you subject yourself to that constraint, it will automatically push you away from things you think you're supposed to work on, toward things you actually like. "Always produce" will discover your life's work the way water, with the aid of gravity, finds the hole in your roof.

One last note before parting that I have is simply this: seek out good teachers.  My wife recently told me what the tuition for a four-year degree at local technical college is: nearly $84,000.  Most of their students do not finish, and most of them are there because they want to make more money.  And, sadly, most of them don't learn a thing--because they're not there to learn, they're there to make more money (via a diploma).  This is not the road to happiness.  It would be much better for those people to find work they love and to see out the best teachers.  I guarantee you that those technical colleges do not have the best teachers.

Thursday, January 24, 2008

IndyTFS January Meeting: These Guys Rawk!

Jamie Kurtz of Open Solutions presented on TFS Work Items.  Now, I really hate going to user group meetings in the midwest, because most of the time the speakers are not really all that knowledgeable about their topic.  This session, however, could have been entitled, "TFS: All Questions Answered."  Between Paul Hacker and Jamie Kurtz, not one question was a stumper.  I learned more about TFS in that two hours than I could have in two days on my own.  It was truly fantastic; they had a great attitude!

Here are some of the things we learned.

  • Customizing Work Item types: workflow, states, custom form fields, custom field controls
  • Details and gotchas on how to get business users setup to edit work items from Excel
  • Details about securing fields and work items
  • Editing MSBuild files to work appropriately with WorkItems

Kudos to both gentlemen.  I encourage anyone using or considering using TFS to member up and start attending meetings.

Saturday, January 12, 2008

List of Links for Learning LINQ

Since I often use this blog as a brain back-up device.  I will add another list of links, this time for learning LINQ.

Building a LINQ Provider

Links to LINQ (another link-post)

How LINQ Works: Creating Queries (part of a series of great posts on LINQ internals)

The .NET Standard Query Operators (slightly out-of-date, but very relevant)

Standard Query Operator Translation (LINQ to SQL)

Friday, January 11, 2008

Happy 70th Birthday to Don Knuth

I still haven't read The Art of Computer Programming, Volume 1, but I'm definitely an admirer of this man.  Here's to many, many more years where we are blessed to have him among us.

Don Knuth is my homeboy

Thursday, January 10, 2008

A Twitter-style Blog Post from a User Group

Larry Clarkin is a developer evangelist for Microsoft based out of Milwaukee.  He gave a talk this evening to the IndyNDA group at the Junior Achievement center on Keystone.  He spent the first twenty minutes of his talk showing us Microsoft's Virtual Earth maps site.  To use the Virtual Earth client libraries you need to include their script library and create a DIV to contain the map renderings.  A very informative site for learning Virtual Earth was demonstrated; it's called "The Virtual Earth Interactive SDK".  Very cool.

He's showed us a pretty tame example of overlaying a Silverlight control on a Virtual Earth map.  The Silverlight control references the map via Javascript.  Pretty simple, but I believe the concept is solid.  You could really have a lot of fun with this approach.

7:09pm and we've been enlightened that SOAP has lost the battle to REST on the public web.  Now we're getting some of the Twitter hype...  boring.  More Twitter, more boring.  I guess I just don't get Twitter. It seems like a way to fill the gaps when you are alone with yourself.  What's next--a microphone for your thoughts?  I will never waste my time reading that crap.

7:23pm and we're learning that RSS is gee-wowie!  "We need more things like RSS."  Good to know.  Larry likes Flickr.

The guy sitting behind me has returned to his seat and reeks of cigarette smoke.  Joy!

Oooh, now I'm learning how to get an ugly slideshow in Blend from a Flickr RSS feed.  It's 7:37pm and he's done--felt longer but under an hour.

The highlight was hearing guys get excited about being able to update Twitter via SMS.  They thought, "Wow, I can point my applications at that feed and then send control codes via SMS."  It feels like you should probably skip the middle-man.  Though, a free SMS to RSS gateway is a fun idea for homebrew mash-ups.

Well, the pizza was better this time.

Wednesday, January 9, 2008

TFS Build Failure: MSBuild Tool missing sgen.exe

We're running TFS 2008 now at my client.  I installed the trial edition just to expedite things, as I'm not the one who works with the licenses.  (You can do an in-place upgrade of the trial to a live license.)  As I was getting the continuous integration build setup for our pilot project, I kept getting a build error similar to the following. 

error MSB3091: Task failed because "sgen.exe" was not found, or the correct Microsoft Windows SDK is not installed. The task is looking for "sgen.exe" in the "bin" subdirectory beneath the location specified in the InstallationFolder value of the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A. You may be able to solve the problem by doing one of the following:  1) Install the Microsoft Windows SDK for Windows Server 2008 and .NET Framework 3.5.  2) Install Visual Studio 2008.  3) Manually set the above registry key to the correct location.  4) Pass the correct location into the "ToolPath" parameter of the task.


Some extensive searching only yielded this post, but I ignored the suggestion that followed the original posting... at first.  Turns out, it works quite fine.  Basically, you should have two registry keys under HKLM\SOFTWARE\Microsoft\Microsoft SDKs



image



The InstallationFolder value in the .NETFramework\v2.0 subkey is the thing we're after in the case.  Make an exact copy of that value under the Windows\V6.0A key.  I did this, as the previously mentioned post suggested, and things worked fine!



Mas Importante!  You may need to install the .NET Framework 2.0 SDK onto your TFS Server/Build Agent machine in order to do the above.

Saturday, January 5, 2008

Lambdas & Closures in C# 3.0

Here's some code the exhibits the creation of a closure in C#.  This was possible with the advent of anonymous delegates in C# 2.0, but it looks a lot cleaner in C# 3.0.

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
public static void Main(string[] args)
{
ClosuresWithLambdas a = new ClosuresWithLambdas();

List<Func<int>> fs = a.GetNumberFunctions();

Func<int> increments_i_func = fs[0];
Func<int> just_returns_i_func = fs[1];

//prints 1
a.PrintReturnValue(increments_i_func);
//prints 2
a.PrintReturnValue(just_returns_i_func);
}

public class ClosuresWithLambdas
{
public List<Func<int>> GetNumberFunctions()
{
//this variable gets included in the closure
int j = 1;

//we use this to return two functions
List<Func<int>> fs = new List<Func<int>>(2);

//don't get confused by the postfix operator
//the f lambda returns j BEFORE incrementing it
Func<int> f = () => j++;

//g just returns the variable j
Func<int> g = () => j;

//add the two functions to the list and return it
fs.Add(f);
fs.Add(g);
return fs;
}

public void PrintReturnValue(Func<int> f)
{
Console.WriteLine(f());
}
}
}


This closure of which I speak is not immediately evident to the untrained eye.  The basic concept in this example is that the variable "j" has to survive past the end of its normal scope, i.e. the execution of GetNumberFunctions.  It has to survive because the two functions passed out of GetNumberFunctions--the lambdas "f" and "g"--refer to "j" outside of the function in which they were defined.  The compiler detects this (perfectly legal) reference as a lexical closure; it generates a class to contain these functions and the variable "j".  Here is that generated helper class viewed from Lutz Roeder's Reflector.



[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
// Fields
public int j;

// Methods
public int <GetNumberFunctions>b__0()
{
return this.j++;
}

public int <GetNumberFunctions>b__1()
{
return this.j;
}
}


As you can probably gather b__0 is "f" and b__1 is "g" (or, "increments_i_func" and "just_returns_i_func" respectively).  They share "j" in the scope of an instance of this compiler generated sealed class instance.  There are other ways for language and compiler to implement closures, but this generated inner class works just fine.  For a practical example of using closures, please see my previous article on doing asynchronous network I/O with closures.

Friday, December 28, 2007

"Fixing" the Enter Key in CreateUserWizard

Problem: You find that when you press the "Enter" or "Return" key on a page that contains the CreateUserStep of your CreateUserWizard (or any other step of any other wizard), your form does not get submitted.  Put another way, something else on the page gets triggered instead of your Create User button.

Solution: In ASP.NET 2.0 the Page.Form has a new property: DefaultButton.  This effectively traps the Enter key and causes the specified button to execute its onclick event handler.  We would like to set this Page.Form.DefaultButton property to the UniqueID property of the CreateUserStep's Create User button.  Unfortunately, we do not have a reliable way of accessing this button in our code-behind.  The solution is to replace it with our own button and wire up the DefaultButton property in the button's pre-render event handler, since it is in a template and we cannot access it directly.

In your .aspx add the following CustomNavigationTemplate to your CreateUserStep:

<CustomNavigationTemplate >
     <asp:Button ID="CreateUserButton" OnPreRender="CreateUserButtonRender" runat="server" Text="Register User" CommandName="MoveNext" ValidationGroup="CreateUserWizard"/>
     </CustomNavigationTemplate>

 

In your .aspx.cs add the following:

protected void CreateUserButtonRender(object sender, EventArgs e)
{
  this.Page.Form.DefaultButton = (sender as Button).UniqueID;
}

Wednesday, December 26, 2007

Choosing a Web Application Server Stack

There's this great book entitled, "The Paradox of Choice: Why More Is Less," that really opened my eyes to a rather non-intuitive way to improve my experience in life.  I won't go into it more than to say the author posits that there is an inflection point where "happiness" does not increase with additional accretion of choices.  This is non-intuitive, but he does a good job of explaining the many factors underlying this phenomenon.  For one, consider the opportunity cost of making a decision; you are buying what you consider the best at the time, but you are also carrying the burden of not having chosen from many other options.  Very often, buyer's remorse sets in after a purchase, and we have no one to blame but ourselves.

So, as I tore through blogs, email archives, tutorials, and documentation today, looking for the "best" platform for my personal pet project, I became acutely aware of just how much choice there is available to build web applications these days.  The result is that it's very late in the day, my weekend spent, and I am writing this blog post to reason aloud, as it were, and to force myself to pick one.

By way of introduction, let me say that my skill set falls squarely in the tried-and-true .NET 2.0 ASP.NET developer model.  I don't do MVC, MVP, Presenter First (PF), O/RM, TDD, DDD, BDD, or any other TLAs, except maybe DRY, SRP, and all those other solid OOP principles.  Also, I'm building this application for myself, by myself, and I can't seem to get a free copy of Visual Studio 2008, so .NET 3.5 and LINQ are out of reach.  I know I need forums, but that's about my only "requirement".  Sure, I've got lots of ideas of what I'm going to build, but I am staring at the blank canvas right now.

Here's the thing: I'm productive.  I build good applications.  I suspect that probably has more to do with my empathy and diligence rather than some prodigious development or architecture skills.  I'm certain I can get better at the latter, but my competitive advantage, if you will, comes from design good interactions.  I'm good a UI design and ideation.  And, frankly, all those TLAs are a bit intimidating, as is the prospect of writing so much more code.

It may sound like I'm leaning toward an ASP.NET 2.0 application, so let me reflect on that.  I am definitely not going that direction.  The major strengths of that platform are:

  • Tooling support---Visual Studio beats vim an SciTE hands down
  • 3rd-Party Controls---Telerik, Infragistics, etc.
  • Familiarity---myself and thousands like me use it every day

Those advantages sound great if you are an IT manager building line-of-business applications.  That's not me.  Among the disadvantages for me are:

  • Mundane---I use it for a living and wouldn't be learning anything new
  • Visual Studio 2005 is not free and the Express editions are...Express editions
  • I won't be purchasing any 3rd-party controls
  • The Page-based application model seems outmoded

So, what are my options?  Well, I would like to try building an application using the MVC/MVP/PF paradigm.  I've invested many hours learning about it, and I want to take a stab at it.  This means, almost certainly, using an IoC container--but which one?  Also, MVC differs significantly from MVP as does PF; which shall I use?  I have to select an environment to do this all in as well.

Supervising Presenter First?

I have settled on Presenter First (PF).  This doesn't have the widespread community support that MVC/MVP have today, which means less tooling and "free" functionality, but that's okay. PF takes SRP and the Humble Dialog to the extreme, forcing you to develop a testable presenter that reads like user stories and easily mocked views and models that can also be tested.  Because PF dictates an stateless and ignorant view, it should be easy to replace and change the UI.  Now, I can definitely say I won't be doing "pure" PF; I plan to allow tuples/ActiveRecord objects into my UI, because I want to use databinding and all the built-in goodness of ASP.NET when it is efficacious to do so.  In this sense, I want PF with Supervising Controller leanings.  

Views: Plain-old Pages

I believe ASP.NET Pages are a very strong candidate for views, despite what I have heard from the ALT.NET crowd.  As a template engine, they are very mature; you can even nest master pages in 2008!  The ASP.NET Membership provider (Authentication, Authorization, Personalization, etc.), declarative security, and databinding are a few great things you get out-of-the-box.  There are lots of controls out there to work in ASP.NET Pages, including all the ASP.NET AJAX stuff.  This absolutely does force you to think about your views in terms of pages at some level, but I believe partial page updates allow user controls to be views as well.

Choosing a Framework

There are lots of choices out there for doing MVC/MVP style ASP.NET application, each with their own peculiar twists.  I have mentioned a couple of these before, but here are the ones I've looked at:

The main problem with each of these is that they are not PF pattern friendly.  That isn't to say that they are antagonistic, not at all.  I'm guessing, relatively blindly, that each of these would be equally difficult to implement PF.  So, what other criteria can I use to cull the herd?  Well, MonoRail doesn't play nice with ASP.NET Pages, so it's out.  Cuyahoga is a real pain in the butt to configure, quite possibly the longest time-to-hello-world [Note: ~400MB QuickTime movie about alternative web frameworks, including plone] of all these frameworks--gone!  Rhino Igloo has some very, very interesting ideas reminiscent of Guice and Spring javaconfig in its used of an InjectAttribute.  WCSF does this, too.  Both of these require that the request is made to and handled by the view (the Page), and they use DI tricks to get the Controller involved.  ASP.NET MVC is using an extensible URL rewrite feature to put the controller first.  This lets us be RESTful in addition to being PF-friendly, e.g. we can handle requests with our controller.

Continuations

My major complaint with all of these frameworks is that don't let me writing applications in a natural way.  I don't write my application in terms of logical processes, instead I implement page flows and deal with all the problems of stateless web applications.  In the nine years that I have been building web applications, my view of what a web application is and should be have changed a lot.  Now, I believe I have seen the promised land, as it were.  Web application servers and frameworks should allow me to develop my applications with logical continuations and take care of the plumbing for me.

REST + Continuations + Presenter First = ?

So, REST is good because it provides clean, bookmark-able URLs, a sort of coherent web-based command-line.  Continuations are good because they let me write applications that simply do not care that the next program event is dependent on transient sessions over a stateless protocol.  The Presenter First pattern is good because its raison d'être is making MVP more amenable to test-driven development.  Unfortunately, there are no ASP.NET web frameworks out there that take these three to be their cardinal virtues.  So, we'll just have to go invent our own.

In a follow-up post to this one, I plan to introduce my prototype for just such a framework.  Utilizing some of the functionality of ASP.NET MVC and Windows Workflow Foundation, along with a lot of new code and concepts, I am building a prototype that I hope proves to be a huge evolution in web programming on the ASP.NET platform.

Friday, December 21, 2007

Liking LINQ: A Question of Efficacy

Consider these two equivalent blocks of code.  First, the LINQ way:

foreach(var assignable in (from Assembly a in BuildManager.GetReferencedAssemblies()
select a.GetTypes() into types
from t1 in types
where typeof(I).IsAssignableFrom(t1)
select t1))
Cache.AddType(assignable.Name, Cache.ContainsType(assignable.Name) ? DUPLICATE_TYPE : assignable);


And, the "normal way":



foreach (Assembly assembly in BuildManager.GetReferencedAssemblies())
foreach (Type type in assembly.GetTypes())
if (typeof(I).IsAssignableFrom(type))
{
if (!Cache.ContainsType(type.Name))
Cache.AddType(type.Name, type);
else
Cache.AddType(type.Name, DUPLICATE_TYPE);
}


I cannot rightly make a judgement call on which way is better.  They have the same result.  Though, it is safe to say that normal way should perform better.  It is also clear, oddly, that the normal way has fewer lines of meaningful code; thus, it is easier to grok.  So, what do you think?  If you had to maintain the code base, which one would you prefer.  FWIW, I'm going to go with the normal way.



This leaves me with the question of efficacy.  Certainly there are niches where LINQ is superior, or the only option, but for general object collection work, should we just ignore this language feature?  Perhaps when PLINQ comes available we'll have a good reason to use it.  Time will tell.

SQL Optimization: Substring Joins

The DBA at my current client has some mad T-SQL skills.  He took a naïve join implementation I had written and improved its performance by three orders of magnitude.

My initial query looked something like this:

SELECT A.*, B.* FROM A JOIN B ON A.Message LIKE '%' + B.Identifier + '%'

Obviously this isn't the best situation in the first place. We don't have a clean relation between these two tables, instead we've got to pick out an identifier (GUID/uniqueidentifier) from a larger text field. Notwithstanding some obvious ETL or trigger possibilities, the statement above seems the simplest solution. The only problem is it is slooow.

The DBA had a great optimization which was essentially to tease out the identifier from the field as you would if you were writing a trigger to create a join column. Putting this in your query allows you to join on this derived column in your code. The performance implications are well above what I would have guessed them to be, operating–as I am–from naïveté. Here's the generalized solution based on our example above:

SELECT B.*, J.* FROM B JOIN
(
  SELECT A2.*,
  CAST(SUBSTRING(A2.Message, A2.GuidStart, A2.GuidEnd - A2.GuidStart) AS uniqueidentifier) AS JoinGuid
  FROM
  (
    SELECT A1.*,
    CHARINDEX('TokenAfterGuid', A1.Message, A1.Start) as GuidEnd
    FROM
    (
      SELECT A.*,
      CHARINDEX('TokenBeforeGuid:', A.Message) + LEN('TokenBeforeGuid:') + 1 AS GuidStart
      FROM A
    ) AS A1
  ) AS A2
) ON B.Guid = J.JoinGuid

Of course, you would expand the wildcard (*) references. This is really a great technique considering the performance ramifications. Certainly in our case, where the query was for a view, this was a wonderful improvement.  Obviously, the best option from a performance stand point would be to tease out the uniqueidentifier in an INSERT/UPDATE trigger, create an index on the new column, and join the tables on that; however, in situations where you don't have the option of doing ETL or triggers this can be useful.

Sunday, December 16, 2007

Liking LINQ: The Learning Curve

This is the second post in a series on Language Integrated Query.  I'm pushing LINQ's buttons and bumping into some of its boundaries. 

Every abstraction leaks at some point, and LINQ to SQL is no exception.  Consider the following code:

NorthwindDataContext d = new NorthwindDataContext(); 
int? quantityThreshold = null;
var sales = from p in d.Products
join od in d.Order_Details on p.ProductID equals od.ProductID
where !p.Discontinued && (quantityThreshold.HasValue ? od.Quantity >= quantityThreshold.Value : true)
select p;



So, when you begin fetching data out of "sales" you'll see the problem.  A run-time error is thrown because the expression tree visitor attempts to greedily evaluate quantityThreshold.Value.  Let's try to move the evaluation out of the LINQ expression.



Predicate<Order_Detail> hasSufficientQuantity = o => quantityThreshold.HasValue ? o.Quantity >= quantityThreshold : true;
var sales = from p in d.Products
join od in d.Order_Details on p.ProductID equals od.ProductID
where !p.Discontinued && hasSufficientQuantity.Invoke(od)
select p;


Well, that doesn't work either.  "The method or operation is not implemented." The expression tree visitor has no idea what this hasSufficientQuantity method is... changing it to hasSufficientQuantity.Invoke(od) reveals that we are barking up the wrong tree, no pun intended.  The error given then is that our Predicate function cannot be translated.  Okay... let's look at why.



This fun LINQ expression syntax in C# is just syntactic sugar for a bunch of extension methods with signatures so jam-packed with Generics, you'd think it was Wal-Mart.  So, we are grateful to our C# language team for the sugar.  But, it does tend to hide what is really going on, making it difficult to figure out why the syntax seems so finicky.  Our LINQ expression above would translate into imperative code similar to the following:



var sales = d.Products.Join(d.Order_Details, p => p.ProductID, o => o.ProductID, (p, o) => new { Product = p, Order_Detail = o }).Where(p => !p.Product.Discontinued && hasSufficientQuantity.Invoke(p.Order_Detail)).Select(p => p.Product);



This isn't exactly pretty, and it doesn't really help us to understand why our function can't be translate, or does it?  Consider what these function calls are doing.  They are taking arguments, primarily Func<...> objects, and storing them internal in an expression tree.  We know from stepping through the code that the execution of our supplied Func<...> objects (the lambda expressions above) is deferred until we start accessing values from "sales".  So, there must be some internal storage of our intent.  Further, the code above must be translated to SQL by the System.Data.Linq libraries, and we can gather from they call stack on our exception that they are using the Visitor pattern to translate the nodes of the expression tree into SQL statements.



What happens when they visit the node that calls invokes the hasSufficientQuantity Predicate?  Well, that code--the Preciate object instance itself--is not available in SQL, so the translation fails.  This seems obvious, but consider that if we were using LINQ to Objects here, any of these approaches would work fine, as the predicate would be available in the execution environment of the translated expression tree, where it wasn't for SQL.



This is a contrived example, of course, and we could "code around" this in any number of ways, e.g.



where !p.Discontinued && od.Quantity >= (quantityThreshold ?? 0)


However, we are still seeing the LINQ to SQL abstraction leak pretty severely.



There are some gotchas out there as well, of course.  Consider the following SQL statement that answers the question, "How many orders have my customers had for each of my products?"



SELECT o.CustomerID, od.ProductID, COUNT(*) as [Number of Orders] 
FROM dbo.Orders o JOIN dbo.[Order Details] od
ON o.OrderID = od.OrderID
GROUP BY od.ProductID, o.CustomerID


How might we attempt to answer the same question with LINQ to SQL?  Notice that we are specifying two columns to group by in our query.  Here's what we might like to write in LINQ:



NorthwindDataContext d = new NorthwindDataContext();
var results = from o in d.Orders
join od in d.Order_Details on o.OrderID equals od.OrderID
group by o.CustomerID, od.ProductID into g
select new {g.CustomerID, g.ProductID, g.Count()};


Of course, this doesn't even come close to compiling.  Here's the right way to do use multiple columns in a groupby: use a tuple!



var results = from od in d.Order_Details
group od by new {od.Order.CustomerID, od.ProductID} into orders
select new { orders.Key.CustomerID, orders.Key.ProductID, NumberOfOrders = orders.Count() };



Once you start getting the gestalt of LINQ, you'll find yourself creating tuples all over the place.  Consider this query expression to retrieve the total sales of each product in each territory:



var territorySales = from p in d.Products
join od in d.Order_Details on p.ProductID equals od.ProductID
join o in d.Orders on od.OrderID equals o.OrderID
join e in d.Employees on o.EmployeeID equals e.EmployeeID
join et in d.EmployeeTerritories on e.EmployeeID equals et.EmployeeID
join t in d.Territories on et.TerritoryID equals t.TerritoryID
where !p.Discontinued
group new { od.ProductID, p.ProductName, t.TerritoryID, t.TerritoryDescription, od.Quantity }
by new { od.ProductID, t.TerritoryID, p.ProductName, t.TerritoryDescription } into sales
orderby sales.Key.TerritoryDescription descending, sales.Key.ProductName descending
select new
{ Product = sales.Key.ProductName.Trim(), Territory = sales.Key.TerritoryDescription.Trim(), TotalSold = sales.Sum(s => s.Quantity) };



The interesting part of that expression is that I created a tuple in my group...by to "select" the data to pass on to the next expression.



What if what we really wanted were the top ten best-selling products in each territory?  Well, there's no "top" LINQ query expression keyword.  The standard query operators include a couple of methods that look interesting: Take(int) and TakeWhile(predicate).  Unfortunately, TakeWhile is among the standard query operators that is not supported in LINQ to SQL.  Why?  Well, it's because you couldn't write equivalent SQL, I imagine.  And, while Take(int) is supported, its not immediately useful in a situation like this where you want to apply it to subsets of your results.  Therefore, a more procedural result seems warranted.  I'll investigate this further in my next post on the topic.



It is interesting to note the situation that arises with certain standard LINQ query operators not being supported by various flavors of LINQ.  Because the standard query operators are implemented using extension methods, every LINQ provider must handle them all, including those they cannot support.  This means throwing the NotSupportedException from the implementation of those methods.  The System.Linq.Queryable static class is where the standard query operators are implemented, defining the operators on IQueryable<T>.  LINQ to SQL classes like Table implement this interface, as do all class that participate in LINQ expressions.



Despite using the same syntax, the LINQ providers will each have their own significant learning curve due to variations in the operators they support and their own quirks. Next time we'll try to implement a top(x) query in LINQ to SQL.