Sunday, September 27, 2009

Library Of The Week: Json.NET

{

In the Christian Bible there’s a story of 10 lepers miraculously healed by Jesus. Even if you don’t believe in Christianity, imagine a leper living in the dregs of society, totally dejected until one day a man shows up and heals him and nine other fellow outcasts. Imagine how happy they should be.

They’d say thank you, right?

In the Bible story, only one of the men returns to say thank you and the other nine are so busy getting back to the lives they wished they had that they forget about the reason they were healed in the first place.

There’s evidence of this kind of lack of gratitude in the ecosystem of free libraries and projects available for .NET developers on the web. I’m a part of that club and not proud of it. I use open source .NET libraries on a regular basis and don’t say thank you. But more than just me, I look at the community participation on CodePlex projects and find it amazing how few people say a simple “thank you.”

With that in mind, I’m going to start profiling libraries that I’ve used with success to build up awareness of their existence and hopefully inspire the people who write them to do more good work since what they do is so tremendously helpful.

The first library I want to profile is the Json.NET library available from CodePlex. It contains a great, intuitive Json serialization/deserialization library. You can point to most serializable objects and convert them to a JSON format with such simple sleight of hand as:

	List<Foo> data = new List<Foo>();
// adds to data
string json = JsonConvert.Serialize(data);




As if that wasn’t simple, retrieving values from their serialized format is also made trivial:





	string jsonItems = GetYourJSON();
List<Foo> data = JsonConvert.DeserializeObject<List<Foo>>(jsonItems);




One great differentiator of Silverlight versus existing web technologies is the ability to have a virtual file system on a client computer. While HTML 5 seems to include facilities for this it is not yet built into existing browsers and even when it is, previous track records on “standards” are a precedent for how balkanized the implementation of them can be. In many areas of web development, you can push the envelope of existing technologies to get what you do out of Silverlight, but the existence of Isolated Storage is a killer feature.



Give Json.NET a try whether you’re doing Silverlight or using a different .NET related paradigm. It’s a great library.



}

Sunday, September 20, 2009

Exception HOF Pattern in C#

{

There’s probably a name for this specific approach but in a personal project of late I’ve found a useful pattern for generalizing my exception handling. I write a ExceptionHelper class that takes a variety of high order function style methods to handle my exceptions in a single spot. Here is a somewhat simple form of what I've been doing:

    public class ExceptionHelper
{

public static void ExecuteWithSuppress(Action code)
{
try
{
code();
}
catch (Exception ex)
{
// pass and ignore the exception
}
}

public static void ExecuteWithHandler(Action code)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine("An exception occured! Details: \n" + ex.ToString());
}
}

public static void ExecuteWithHandler(Action code, string errorMessage)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine((errorMessage.Length > 0) ? errorMessage : ex.ToString());
}
}

public static void ExecuteWithHandler(Action code, Action onError)
{
try
{
code();
}
catch (Exception ex)
{
if (onError != null)
{
onError();
}
}
}

public static void ExecuteWithHandler(Action code, Action onError, string errorMessage)
{
try
{
code();
}
catch (Exception ex)
{
Console.WriteLine((errorMessage.Length > 0) ? errorMessage : ex.ToString());
if (onError != null)
{
onError();
}
}
}

public static bool ExecuteWithNotificationButIgnore(Action code)
{
bool ret = true;
try
{
code();
}
catch (Exception ex)
{
ret = false;
}
return ret;
}

public static void ExecuteWithLogging<T>(Action code) {
try
{
code();
}
catch (Exception ex)
{
if (ex is T) {
Console.WriteLine("Logging exception " + ex.ToString());
}
}
}

public static void ExecuteWithLogging(Action code, Action<Exception> handles) {
try
{
code();
}
catch (Exception ex)
{
handles(ex);
}
}

}


At this point I use it in a lot of places, here are a few scenarios:



ExecuteWithSuppress(Action code) – code that has a low impact of failure or an expected failure under some conditions. For example, a client of mine once had a legacy database they wanted to me parse a “name” field from. We set up basic heuristics to separate out first and last and so on, but on failure we just returned a blank string.



ExecuteWithHandler(Action code) – you have some generalized exception handling to do something: prompt the user, do logging, etc. ExecuteWithHandler(Action code, Action handler) – you get to pass in the exception handling you want


ExecuteWithHandler(Action code, string errorMessage) – pass a custom error message


ExecuteWithNotificationButIngore(Action code) – try to execute some code but return a boolean to indicate success


ExecuteWithLogging<T>(Action code) – run some code, indicate the types of exceptions to differentiate


ExecuteWithLogging(Action code, Action<Exception> handles) – pass a method to catch be passed the exception that occurs.




The resulting code I write with this pattern, I find pleasant. Here are some examples:



    string userName = String.Empty;
ErrorHelper.ExecuteWithSuppress(() => userName = doc.Descendants("Name").First().Value);
return userName;


if (ErrorHelper.ExecuteWithNotificationButIgnore(() =>
{
SendEmail();
}
else
{
// message not delivered, etc, etc.
}


I want it to be absolutely clear that this is not a replacement for try/catch/finally logic where it is warranted. It is simply an alternative that can help to keep code clear and readable. As with many things in software, there is taste involved in when and where something like this is leveraged. But it works well enough for me that I thought I’d share.



}

Saturday, September 19, 2009

FizzBuzz Functional

{

I’ve been reading Tomas Petricek and John Skeet’s Functional Programming for the Real World. I’m hoping I can, as Steve McConnel says, program into1 my C# projects some elements of functional problem solving. As I was working to grok the beginning portions of the book I thought I’d rewrite FizzBuzz since I’ve aleady posted a few versions of a solution. Here is my solution:

Func<int, int[], bool> isMultiple = (n, n2) => n2.Any(m => n % m == 0);
Func<int, int, string, string> fb = (n, n2, s) => (n % n2 == 0) ? s : String.Empty;


foreach(var i in Enumerable
.Range(1, 100)
.Select(n =>(isMultiple(n, new int[]{3,5}))
?fb(n, 3, "Fizz") + fb(n, 5, "Buzz")
:fb(n, n, n.ToString())
)Console.WriteLine(i);


Another version, using ForEach on a List<T>:



Func<int, int[], bool> isMultiple = (n, n2) => n2.Any(m => n % m == 0);
Func<int, int, string, string> fb = (n, n2, s) => (n % n2 == 0) ? s : String.Empty;

Enumerable
.Range(1, 100)
.Select(n => (isMultiple(n, new int[] { 3, 5 }))
? fb(n, 3, "Fizz") + fb(n, 5, "Buzz")
: fb(n, n, n.ToString()))
.ToList()
.ForEach(num => Console.WriteLine(num));


I'm just starting to wade into using F# but I'm hoping to start building my proficiency the further I get into the book



1"Don't limit your programming thinking only to the concepts that are supported automatically by your language. The best programmers think of what they want to do, and then they assess how to accomplish their objectives with the programming tools at their disposal." – Steve McConnell, Code Complete 2nd Edition



}

UI Inspiration for Silverlight’s Blank Slate

{

I’ll admit that I spent an inordinate amount of time last week thinking about dialog boxes. Silvelright’s canned prompt comes courtesy of a call to MessageBox.Show which displays the browser’s native modal dialog. I think you get the same thing from HtmlPage.Window.Alert too. Needless to say, these should leave you wanting.

A good place to start, rather than wasting the better part of a day playing around like me, is to begin with a really good convention rather than making something “original.”

So without further ado, I’m linking to a nice PSD courtesy of teehan+lax that contains visual styles for many of the iPhone’s UI Elements. I’ll have to build a nice workflow to get things like this into XAML.

 

One more philosophical note (noted below so that if you just needed the link you won’t be daunted by my long windedness) – almost 100 episodes ago the Hanselminutes podcast featured Scott interviewing David Heinemeier Hansson and Martin Fowler at RailsConf 2007. When talking about UI design and originality here is what DHH had to say:

“I think the low level of
expressiveness that we have in HTML and CSS
and JavaScript is actually a huge boon to most
applications that constraints are a good thing,
that constraints leads to better applications when
we don’t need to reinvent everything
. When you
just have blank canvas where you can paint
whatever you want on it, you pretty much end up
with something “original” every time; and I don’t
think originality in UI design is necessarily a good
thing; I just think actually most of the time it's a
bad thing.”

I agree with DHH on this point. It’s worth listening to the entire podcast to put some context to his comments. Where my opinion veers from his or at least my hope for Silverlight is that conventions more powerful than those of HTML/CSS/JavaScript begin to come together for developers and they spend less time thinking about a blank slate and more about how their application works with the benefit of a better experience. Themes are a good step in this direction but things like dialogs go beyond to interactions as opposed to just colors and gradients.

}

Thursday, July 16, 2009

Why IE6 Continues To Ruin My Life

{

Via a good friend, this post confirms that many of us are in the same situation: corporate IT people force users to stay in IE6 which forces, in turn, all of us developers to suffer by having to support it. The post, written from an inside Digg perspective doesn't tell the whole story so I’d like to add one dimension. Many corporate environments are in this unfortunate cycle based on the inability to project abstract costs, that is to say that often (always?) software is rushed through and “finished” in an agile, YAGNI kind of way, and after the fact managers1 have a hard time capturing the costs it takes to support legacy browsers because of “finished” software. The two development efforts are seen as separate, so the extra time in new development doesn’t factor into the decision to keep what is old.

Cheers for Virtual PC and the ability to test things out without having it installed locally but nevertheless I’d like to force everyone to upgrade and forget that browser ever existed.

Side note, if you are fortunate enough to force an upgrade, here is some help.

1I’m sure special kinds of managers are able to guess this in and make good decisions but they are a rare breed and the elixir they drink is hard to find.

}

Wednesday, May 06, 2009

Proper 0.2: INotify, DependencyProperty Support

{

Several years ago, in a land of Visual Studio 2005 and no CodeRush, I made a tool called Proper to automate the monotony of creating properties. You just type something like “int Foo;string Bar;” and you’d get basic property generation. You can use shortcuts to types by typing an undercore “_” character. For example, “i_” will pop up int, “dt_” would pop up DateTime (You can also create your own). It’s funny how the stuff that you’re half serious about can last so long – at the time I wanted to write something useful entirely in JavaScript and to experiment a little with JQuery.

The tool suffered neglect for the next few years until recently when I began working with Silverlight and was amazed at how a similar monotony (and more code!) accompanies using INotifyPropertyChanged and implementing dependency properties. I remembered my old tool and added support for generating them there. Here are some screenshots that should illustrate how it works (you select “advanced options” and then select a few checkboxes, in a nutshell). I’ll update the feature to report bugs – I’m sure there are a few. I also neglected to update it for VB.NET – I’ll do that over the next few weeks.

If you do spot a bug, let me know. There are a few new goals I have with the tool, the first of which is refactoring some of the embarrassing JavaScript I crufted together to make this work. I remember Kevin Dangoor talking about Embarrassment Driven Development (when your code is so embarrassing that you’re motivated to update it); that’s the one thing about JavaScript – you can’t hide the way things are constructed. :)

}

Friday, April 24, 2009

Using IronPython For Converters in Silverlight

{

 

Tim Heuer has a great intro post on Silverlight data binding and value converters. The concept is a really nice one but I’m not wild about having to write a class that implements the IValueConverter interface every time I need some ad-hoc tweaking of the values I get from being data bound and how I’d like to use them within XAML. What set me off this track was a case where I simply needed to invert a boolean – what should just be “not myvalue” ended up requiring a class, an interface, and so on.

Dynamic languages excel at this sort of thing and since they support the ability to evaluate code on the fly I thought it would make sense to write a single implementation of IValueConverter and host Python inside of it to evaluate binding expressions that are passed in. Here is what that might look like:

public class PythonExpConverter : IValueConverter
{
private ScriptEngine _engine;

public PythonExpConverter()
{

ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
setup.DebugMode = true;
var runtime = new ScriptRuntime(setup);
_engine = Python.GetEngine(runtime);

}

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object result;
string python = parameter.ToString()
.Replace("value", value.ToString());
try
{
result = _engine.Execute(python);
}
catch (Exception ex)
{
// pass, just use original value
result = value;
}
return result;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// same concept as above
return value;
}
}


No magic, just instantiate the Python runtime and then proceed to leverage it in the Convert phase by taking a string as the parameter for the conversion method. Use value as a keyword in your Python expression to get at the value of the underlying data.  Once this is added as a static resource, you can leverage it in many ways. For example, if I had a class “Person”:



public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool OnVacation { get; set; }
public double Balance { get; set; }
}


Let’s say I’m binding to an instance of Person (yeah, very contrived) with the following template conversions:

1. Uppercase last name.


2. If OnVacation is true, disable a link to their schedule.


3. Format balance using some currency specific format.


Here is the XAML that leverages my single converter for all of the above:



<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="First Name" Width="100" />
<TextBlock Text="Last Name" Width="100" />
<TextBlock Text="Is Active" Width="100" />
<TextBlock Text="Rating" Width="100" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" Width="100" />
<TextBlock Text="{Binding LastName, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'value\'.upper()}" Width="100" />
<HyperlinkButton Width="100" NavigateUri="http://foo" Content="View"
IsEnabled="{Binding OnVacation, Converter={StaticResource PythonExpConverter}, ConverterParameter=not value}" />
<TextBlock Text="{Binding Balance, Converter={StaticResource PythonExpConverter}, ConverterParameter=\'%2.2f\' % value}" Width="100" />
</StackPanel>
</StackPanel>


This is a very powerful approach since the limitations you hit will probably be born by a limitation in skill with Python or your dynamic language of choice rather than the approach. 



}

Monday, March 23, 2009

Almost Famous

{

Yours truly, looking embarrassed in the middle.

 

Here is the link to Phil's write up.

}

Friday, March 20, 2009

Voidspace on Dot Net Rocks

{

Michael Foord, aka Voidspace, is on a Dot Net Rocks episode talking about IronPython.

}

Wednesday, March 04, 2009

Currying with C# and Algotron

{

Friend and coworker Algotron just posted an intro and sample of currying with C#. I decided to try out currying with the idea of successive regular expressions on a string array - I found it easy to approach first with anonymous delegate syntax and then use lambda expressions. Once this was in place it was easy to understand the use of an extension method to curry any binary function. 

Func<string, string[], Func<string, string[]>> fil = 
delegate(string pattern, string[] lines){
return delegate(string pattern2)
{
return lines
.Where(p=> Regex.IsMatch(p, pattern))
.Where(p => Regex.IsMatch(p, pattern2))
.ToArray();
};
};


Func<string, string[], Func<string, string[]>> regFil =
(pattern, input) =>
(pattern2) =>
input
.Where(p => Regex.IsMatch(p, pattern))
.Where(p => Regex.IsMatch(p, pattern2))
.ToArray();

// assume some address data
string[] data = new string[]{"1234 Somewhere", "this", "777 dakota"};

var filterNumeric = regFil(@"\d", data); // make sure it has a number
var filterUCase = filterNumeric("[A-Z]"); // make sure it has an uppercase character

Console.Write(String.Join(",", filterUCase));


That's cool stuff, worth looking at for a while to try to understand.



}

Tuesday, March 03, 2009

IronPython + SilverlightFX

{

SilverlightFX is an interesting library for declaratively attaching behaviors to objects in XAML. People new to the Silverlight world will like how they can use it to get simple animations out of simple code. Here's a step by step:

1. If you don't have it done already, set up an IronPython / Silverlight project.

2. Download SilverlightFX

3. Copy SilverlightFX binaries into your /app directory.

3. Edit the AppManifest.xaml to include the SilverlightFX binaries. Here is an example:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
RuntimeVersion="2.0.31005.00"
EntryPointAssembly="Microsoft.Scripting.Silverlight"
EntryPointType="Microsoft.Scripting.Silverlight.DynamicApplication">
<Deployment.Parts>
<!-- Add additional assemblies here -->
<AssemblyPart Source="Microsoft.Scripting.ExtensionAttribute.dll" />
<AssemblyPart Source="Microsoft.Scripting.Silverlight.dll" />
<AssemblyPart Source="Microsoft.Scripting.Core.dll" />
<AssemblyPart Source="Microsoft.Scripting.dll" />
<AssemblyPart Source="IronPython.dll" />
<AssemblyPart Source="IronPython.Modules.dll" />
<AssemblyPart Source="System.Windows.Controls.dll" />
<AssemblyPart Source="System.Windows.Controls.Data.dll" />
<AssemblyPart Source="Silverlight.FX.dll" />
</Deployment.Parts>
</Deployment>


4. Edit your app.xaml file to include references to the SilverlightFX namespaces. Here is an example:



<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="System.Windows.Controls.UserControl"
xmlns:fxui="clr-namespace:Silverlight.FX.UserInterface;assembly=Silverlight.FX"
xmlns:fxeffects="clr-namespace:Silverlight.FX.UserInterface.Effects;assembly=Silverlight.FX"
>


5. Party on with some declarative effects.



<Border Grid.Row="1" x:Name="redRect" Opacity="0.2">
<TextBlock x:Name="outPut" TextWrapping="Wrap"
Text="Lorem ipsum dolor sit amet,..." />
<fxui:Interaction.Behaviors>
<fxui:HoverEffect>
<fxeffects:Fade FadeOpacity="1" />
</fxui:HoverEffect>
</fxui:Interaction.Behaviors>
</Border>


6. Read Nikhil's related blog entries.



}

Thursday, February 26, 2009

DLR + IronPython + Silverlight in 5 Steps (with pictures)

{

A simple step by step1.

1. Download the Silverlight DLR SDK

2. Map the binaries (the folder with Chiron2 et. al.)  in your PATH Environment variable.

3. Download this starter template.

4. Run chiron /w from the command line in the directory of the starter.



a) Make sure you're in the correct folder
b) The command is
chiron /w
c) You'll get a message that Chiron is serving at http://localhost:2060a

5. Navigate to http://localhost:2060 and hit index.html to see what's up.



 
The starter3 should make it easy to get up and running. Open the app.py and app.xaml files and you will be able to modify the xaml and write code to customize it into your own creation.

1. Michael Foord aka Voidspace is the guy when it comes to IronPython. He wrote a book on it. He has a "getting started" tutorial that is much more extensive if you want more details. His tutorial isn't as terse so I thought I'd write this one for people who just want a step by step before poking around. There are other people like JimmyThinking who offer a lot of help to beginners but lean towards IronRuby.

2. The name Chiron for a tool makes me think about a few things: first, being born out of time since most BigCo shops today name computers and tools in a hollow, mechanistic fashion. In the salad days of computing on Unix, tools had cool names like ed or yacc. The second thing I think is that Dmitri (and I'm sure there's an "et. al.") must be a cool, interdisciplinary fellow to come up with a name like that.

3. The exchange in the sample is from Swahili classes at Rusinga Primary School in Nairobi.

}

Wednesday, February 25, 2009

nRegex 9

{

I've been getting up to speed with Silverlight and decided to rewrite nRegex to leverage it as a client side processor for what the original nRegex shipped to the server with AJAX calls.  In the original nRegex this worked fine until you had to deal with large documents but once you were in the large document space things began to go awry. My solution was to allow for a "manual" evalution of the regular expression (rather than a time interval based evaluation) but I'm hoping that Silverlight will prove an elegant solution since not only can it harness the power of the client but it also has features to run code asynchronously.

In my first iteration I leveraged a lot of the JavaScript interop for the Silverlight control and avoided XAML for display. I think in the next iteration I'm going to spend more time on displaying results via XAML.

Feel free to present any comment or suggestion on nRegex and its direction.

}

Thursday, February 19, 2009

DDD

{

Not to be confused with D&D... Domain Driven Design for those of us who don't keep up with all the acronyms.

I'm seeing this more and more in places I lurk. DDD is the next buzz like Agile?

Next steps: relisten to Hanselminutes, ALT.NET Podcast, lurk on DDD site, and pay more attention on the ALT.NET mailing list.

}

Friday, January 02, 2009

Another "Dead Java" Proclamation

{

I was browsing to Elliote Rusty Harold's blog to see if he had any predictions for XML in 2009 and to my surprise I found his post: "Java is Dead. Long Live Python!"

My familiarity with Harold comes from a time in my life where I worked heavily with XML and later Java and it was his books on both subjects that proved invaluable when I hit my rather frequent roadblocks.  As invested as he is in Java, what would make him say as much? In a nutshell, it's the way the language has been implemented over the last few years - claims which, even if you don't agree with the premise that Java is "dead like COBOL", are worth some attention.

What is interesting to me about Java right now is not the language itself but dynamic languages and their platforms built on top of the JVM. JRuby is what comes to mind first and I'm recently interested in what a JRuby/Glassfish world looks and feels like.

}

Wednesday, December 31, 2008

Using SGMLParser With IronPython

{

Mark Pilgrim's excellent Dive Into Python has a section on using SGMLParser and having seen nothing similar (and imagining its many uses!) I thought I'd give it a whirl in IronPython. I thought a good proof of concept would be creating a database out of link heavy sites.  Since I visit Arts & Letters Daily every so often and the closet intellectual in me likes to hang onto what I find there, I thought I'd target it:

import urllib2
import sgmllib
from sgmllib import SGMLParser

import clr
clr.AddReference("System.Data")
clr.AddReference("System.Net")
from System import *
from System.Data import *
from System.Net import *

class AlReader(SGMLParser):
def reset(self):
SGMLParser.reset(self)
self.urls = []
self.pieces = []
self.track = 0
self.prePend = "No Category"
self.counter = 0

def start_a(self, attrs):
href = [v for k,v in attrs if k == "href"]
key = [v for k,v in attrs if k == "name"]
if href:
self.urls.extend(href)
self.track = 1
elif key:
self.prePend = attrs[0][1]

def handle_data(self, text):
if self.track:
self.pieces.append("|".join([self.prePend, text]))
self.counter = self.counter + 1

def end_a(self):
self.track = 0

def get_links(self):
links = []
for i in range(0, len(self.urls)):
links.append("|".join([self.pieces[i], self.urls[i]]))
return links
#print "%s %s" % (self.counter, "Total links")

def get_link_datatable(self):
d = DataTable()
d.Columns.Add(DataColumn("Category", Type.GetType("System.String")))
d.Columns.Add(DataColumn("Site", Type.GetType("System.String")))
d.Columns.Add(DataColumn("Url", Type.GetType("System.String")))

for text in self.get_links():
newRow = d.NewRow()
newRow["Category"], newRow["Site"], newRow["Url"] = text.split("|")
d.Rows.Add(newRow)

return d

response = urllib2.urlopen("http://www.aldaily.com")
a = AlReader()
a.feed(response.read())
linkdata = a.get_link_datatable()
# write it out to prove we got it.
ds = DataSet()
ds.Tables.Add(linkdata)
ds.WriteXml("c:\\temp\\arts and letters links.xml")


If you find tihs interesting do make sure you look at Pilgrim's chapter on HTML Processing



}

Saturday, December 20, 2008

Parameterized IN Queries

{

I haven't listened to the podcast yet but saw a cool trick from Joel Spolsky on approaching parameterized IN queries. Purists will bemoan its lack of premature optimization but I think it's novel enough to study because of the approach: using the SQL LIKE operator on your parameter rather than a field, which is what people like me are used to. There's code on the StackOverflow post but I thought I'd paste some of the poking around I did in Sql Management Studio:

-- setup
CREATE TABLE Person
(
PersonID INT IDENTITY(1,1) PRIMARY KEY,
FirstName VARCHAR(50) NULL
)
GO

-- some data
INSERT INTO Person VALUES('David')
INSERT INTO Person VALUES('Jonathan')
INSERT INTO Person VALUES('Zlatan')
INSERT INTO Person VALUES('Trilby')

-- here's the magic
DECLARE @FirstName VARCHAR(50)
SET @FirstName = '|David|Trilby|'
SELECT * FROM Person WHERE @FirstName like '%|' + FirstName + '|%'

-- ported to a proc
CREATE PROC uspPersonSelector
@FirstNames VARCHAR(500)
AS
SELECT * FROM Person WHERE @FirstNames like '%|' + FirstName + '|%'
GO

-- showing it works
uspPersonSelector '|David|Trilby|'

-- somewhere in the netherworld of C#:
/*
string[] names = {"David", "Trilby"};
SqlCommand cmd = GetACommandFromSomewhere();
cmd.Parameters.AddWithValue("@FirstNames", "|".Join(names));
*/

--teardown
Drop Table Person


 



}

Friday, December 19, 2008

Programmers as Goalkeepers

{

The 8th annual New York Times magazine Year in Ideas featured a section on Goalkeeper Science profiling this paper by some Israeli scientists called Action bias among elite soccer goalkeepers: The case of penalty kicks. In looking at the approach of keepers in some 286 penalty kicks they found that though 94 percent of the time they dived to the right or left, the chances of stopping the kick were highest when the goalie stayed in the center. The researchers theorized that the reason keepers behaved in this way was that they were afraid of appearing that they were doing nothing.

Immediately I remembered a blurb from an Paul Graham's What Business Can Learn from Open Source  essay where he expressed a similar dynamic for programmers:

"The other problem with pretend work is that it often looks better than real work. When I'm writing or hacking I spend as much time just thinking as I do actually typing. Half the time I'm sitting drinking a cup of tea, or walking around the neighborhood. This is a critical phase-- this is where ideas come from-- and yet I'd feel guilty doing this in most offices, with everyone else looking busy."

I wonder what Paul would say about the IBM commercial on ideating in which concludes that people should "start doing" after showing an image of people laying inert on an office floor, a stark portrayal of how a manager at IBM might see someone like Paul Graham.

As programmers much of what we should do may not appear to be work for the nonprogrammer and as a result many of us end up doing it at home. I spend a lot of time at home exploring different technologies in a kind of tangential approach that wouldn't look like "working" at work but often my best ideas and solutions come from here.  I also spend a lot of time reading technical books and blogs.

I'm wondering what it would look like if we could step back and look in a quantitative way at the performance deficits resulting from the desire to look busy at work. What would the workday look like? I'm wondering what an hour for reading, a few hours for exploratory/research programming, and the rest as project time would do for my own productivity.

If programming was goalkeeping was programming, Edwin Van der Sar would be quite the Python hacker. 

}