Friday, October 31, 2008

LINQ to SQL death rumors

{

I think it all started with this post from Tim Mallalieu reporting some directions for LINQ to SQL and the ADO.NET Entity Framework. Ayende and others have had some strong reactions (LINQ to SQL is dead) and there's now a StackOverflow thread you can use to follow the discussion.

It will be interesting to track over the next few days what other responses pop up. A few things that come to my mind:

1. This is an opening for people using Linq to SQL to migrate to SubSonic or NHibernate. I've been using SubSonic lately and enjoying myself quite a bit.

2. A big disappointment for people like Benjamin Day who I saw speak at VSLive and who have incoprorated LINQ to SQL into their development projects. Next time wait for Microsoft to 2.0 something before spending too much time working it into your dev cycle.

3. I wonder if Microsoft hasn't thought of spinning off some of the tool makers as different companies. Perhaps there is an MBA out there who could draw some charts and convince management to have ADO.NET Entity Framework and the LINQ to SQL folks compete/copy in the same space. If the team isn't fully formed, why not make one? And then how cool would that be: profit centers that encourage developers to use Microsoft tools and competition to get the best ideas out the door. The trade off of Balkanization versus One True Product is that the former will mean that cool new ideas belong to you - the company won't have to get the ideas from outside sources. 

4. I wonder if we aren't moving towards a tipping point of Microsoft developers "getting" open source and shifting their tool/framework usage outside of Microsoft. I know lots of people who won't use __anything__ unless it has a Microsoft logo because it feels safer and more commoditized. Moves like this seem to go against that since open source projects tend to live a longer time and technologies / frameworks from companies become "obsolete" (how many versions of ADO can you count?) because of a product cycle that requires new purchases every 2 years or so. I would argue with my boss on a new project that it's safer to use NHibernate than ADO.NET Entity Framework if this indicates a chance that the Entity Framework could be the next LINQ to SQL project.

}

Thursday, October 23, 2008

.NET Survey

{

Scott Hanselman did a survey of .NET usage and posted results on his blog. A few interesting notes:

1. Heavy use of older stuff: ASMX, DataSet, WebForms, Windows Forms
You'd be hard pressed to find new blog entries on it but it shows that older (tried) technologies don't sync up with what's popular. The last few projects I've worked on have had development cycles that far exceed the excitement of their underpinning technology. One needs to remember that excitement and hype aren't what make something useful, it's use. So the people who talk down DataSets do so in the face of what obviously works for a silent majority who are busy getting stuff done.

2. Some new stuff won't take, some new stuff takes off
The respondents using CardSpace and WorkFlow are dismal. I can match the "unscientific" survey with a lot of my own experience in the last few years and conclude it's within a broader trend. On the other hand, LINQ To SQL has very heavy use for something relatively new, almost on par with ADO DataSets which one could argue are in the same competitive space. That says to me that in some cases adoption is just slow when there's a "legacy" counterpart for a technology but in others, when the new technology is compelling, people take to it very quickly.

3. WinForms > WPF
More than twice the respondents but here's my conclusion: it's all about the toolset, not the technology. WPFs tools are not on par with their WinForms equivalents. The dual Blend + VS strategy doesn't make sense for a large majority of us who don't have full time designers we work with and the lack of built in controls (such as a DataGridView) mean as cool as rounded edges are, function trumps form when programming.

4. MVC?
Last I checked this was *just* released as a beta. More people claim to use that than WPF which seems to indicate a Hanselman type majority in respondents. Even if I wanted to jump into MVC, until it's at a "1.0" release I couldn't (and I'm wondering how others seem to be doing so) justify starting or migrating a major product to a product/framework that isn't yet complete.

}

Wednesday, October 22, 2008

Recursive Copy ala LINQ

{

Tonight I needed to copy a bunch of images, no matter their level in the hierarchy to a single folder. Cake walk with C# and LINQ, I'll post the Python equivalent tomorrow.

string sourceDir = @"C:\thesource";
string targDir = @"c:\thetarget";
var files = new DirectoryInfo(sourceDir).GetFiles("*", SearchOption.AllDirectories)
.Where(p=> !p.Extension.Contains("db")) // exclude the pesky windows db file
.Select(p => p.FullName);
foreach (string path in files) {
File.Copy(path, Path.Combine(targDir, Path.GetFileName(path)));
}


 



}

Monday, October 20, 2008

Better Know a Framework: Zip / Package Multiple Files in C#

{

Making a single archive out of multiple files in .NET is easy once you know where to look but I spent far too long realizing there is a System.IO.Packaging namespace (not in the mscorlib, but you need to reference WindowsBase assembly).

// target file
string fileName = @"C:\temp\myZip.zip";

// point to some files, say JPEG - did I say I love LINQ?
var filesToZip = new DirectoryInfo(@"c:\temp\").GetFiles("*.jpg").Select(p => p.FullName);

using (Package exportPackage = Package.Open(fileName))
{
foreach (var file in filesToZip)
{
using (FileStream fileStream = File.OpenRead(file))
{
Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(file), UriKind.Relative));
PackagePart packagePart = exportPackage.CreatePart(partUriDocument, System.Net.Mime.MediaTypeNames.Image.Jpeg);
CopyStream(fileStream, packagePart.GetStream());
}
}
}

// somewhere else, the CopyStream
private static void CopyStream(Stream source, Stream target)
{
const int bufSize = 0x1000;
byte[] buf = new byte[bufSize];
int bytesRead = 0;
while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
target.Write(buf, 0, bytesRead);
}


The trap in looking for this was that searches for this all point towards the GZipStream which is nice for a single file but not applicable for packaging multiple files. In my case I wasn't even interested in compression, just a single archive. You'll find additional documentation for the library here.



I'm half tempted to write a nifty tool in IronPython for command line packaging but in a world with 7-zip, that's simply foolish.



}

Saturday, October 18, 2008

Mashing Up: JQuery and Windows Forms, a first WIB

{

A lot of people are down on Windows Forms as something passe. I have a feeling there are a lot of people like me who not only must use it for practical reasons but also think there are advantages to fat clients that sit on the Windows platform. I'm getting to a point where I will start doing more than poking around with WPF but at present two factors hold me at bay: the control library is not robust enough (another tutorial of how to make a custom button in blend isn't incentive enough) and XAML is still a bit daunting for what usually end up being rather involved UIs. Here, for example, is a UI from an application I've been working on for a while (small intentionally to impart an idea of complexity without revealing any details):

I think a lot of "do it in XAML" problems can be solved with a more web development style paradigm in Windows. A simple example is template driven databinding with styles. That's easy to do in web applications but a little less flexible in a control based world (think a GridView with CSS versus the Windows Forms DataGridView).

As a proof of concept I decided to use the System.Windows.Forms.WebBrowser in a Windows Forms application to get cool features from JQuery while maintaining the strengths of a windows app. Here's the scenario: a photo manager application. It builds and manages a database of photos from a digital camera. Rather than uploading the 300+ pictures taken in a single session to Flickr (or in conjunction with that act) one can open it up, start annotating their files and saving the comments to a portable "database" that they can back up along with the files on their home machine.  On any machine with the application they point to the directory and can view their original comments along with the pictures. Here is a screen shot:

The strength in this scenario of Windows Forms is the ease with which one can build the editing interface: textboxes, buttons and other "drag / drop" pieces of the control library. The strength of JQuery is in the display - I've chosen to use an animation and the accordion to spruce up the interface where the user looks at their photos.

You can download the whole thing here. (Very 0.1 but posted as an example/idea - just use the next / previous buttons to view some photos, get a feel of things).

I wonder if this paradigm can be a kind of Ajax "aha" moment; Ajax was centered on the use of a single, relatively simple MSXML component. Though System.Web.Forms.WebBrowser is not simple, it's a single component that has a lot of room for leverage.  Ajax set up some pretty standard protocols / approaches to using asynchronous HTTP requests from a client - I think an interesting parallel could exist in wrapping jQuery and Html controls into a kind of framework that is easy for any developer to use with the WebBrowser control. Imagine a grid you drop with some properties and a CSS.  The last thing that made Ajax pop was the catchy name. I love naming things myself so I've been calling this kind of application a WIB (Windows + Web) but perhaps there's something more catchy one could use.

Just some ideas, I'd be curious in the following:

1. Any existing applications written with this approach.
2. Any potential applications that could benefit with the pros of both Windows and Web
3. Any glaring shortfalls

}

 

ps. Thanks to Corey for encouragement on the blogging tip.

Wednesday, October 01, 2008

YUI File Disjoin Complexity HELP

{

I got a little help yesterday from Dav Glass and Eric Miraglia for my issue on selection of YUI javascript files. What I'd had distributed over a bunch of files is now:

<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo-dom-event/yahoo-dom-event.js&2.5.2/build/animation/animation-min.js&2.5.2/build/element/element-beta-min.js&2.5.2/build/container/container_core-min.js&2.5.2/build/menu/menu-min.js&2.5.2/build/button/button-min.js&2.5.2/build/connection/connection-min.js&2.5.2/build/datasource/datasource-beta-min.js&2.5.2/build/datatable/datatable-beta-min.js&2.5.2/build/tabview/tabview-min.js"></script> 



Hm... a bit better. Both Dav and Eric confirm that the canonical solution to this problem is to spend some quality time at the YUI Configuration Site which will allow you to pick the widgets and utilities you've leveraged in order to combine it into a more simplified call.



A someday project: the following style of implementation to make the reference a bit more crisp (I didn't add everything from above, but the pattern should be easy to observe):



<script type="text/javascript" src="http://yui.yahooapis.com/combo/2.5.2/dom-event&animation-min&element-beta-min&container_core-min"></script> 




 



Anyhow, thanks for the help.



}

Tuesday, September 30, 2008

YUI File Disjoint Complexity FAIL

{

So here's what has been getting my goat for a while with YUI and a very smple application I've been using it to build.


So for said application, I have to reference 12 separate Javascript files along with 5 separate CSS files.  All for this simple interface (datatable, tabs, button, ajax (connection), events and maybe a few more things I am not remembering):

This type of complexity is what makes YUI daunting for many developers and difficult to maintain; over at nRegex I'm referencing a bunch of older versions of YUI and if/when I do decide to update there will be quite a few places in which compatibility and errors have the potential in manifesting themselves.

YUI controls are nice once working but I'm at the point of wondering if this kind of disjointedness should lead me towards jQuery or Dojo. Especially with Microsoft's recent adoption of jQuery, I'm leaning in that direction. But I don't want to be rash so I'll ask:
1. What is the canonical solution e.g. blessed by Yahoo! (I see a YUI loader of some kind)?
2. What does that look like with the 5 CSS and 12 *.JS files I've got above?

}

Monday, July 28, 2008

Reading Source, Minima III

{

As my reading of Minima source code continues I wanted next to comment upon the database interaction which is novel (to me at least) in that it is exclusively a LINQ implementation with no stored procedure or ADO.NET implementation.  I've seen LINQ quite a bit, but many using it seem to stick to using the query syntax rather than using raw lambda expressions.  All the LINQ in Minima that I've seen uses lambda expressions and I've  come to appreciate it as a clean, sparse syntax.  To illustrate a more trivial example, assuming I have a table Users with Username / Password columns I wanted to verify for access. The first step with all things LINQ is to make your data model, which amounts to a DBML file that you map database objects to with drag and drop. Next you can write query expressions to pull data out of the database - notice that the db variable here points to the data model as embodied in a "data context" object:

            var authUserQuery = from u in db.Users 
where u.Email == Login1.UserName && u.Passphrase == Login1.Password
select u;


Unfortunately the query expressions return an IEnumerable<T> that doesn't support a Count or Length property. It's a somewhat inflexible thing that in my *very* limited experience is useful mainly for iterating with a ForEach - and I suspect it's reasons like this that led Betz to using a lambda syntax that is much cleaner and gets more bang with less code:



            Func<Data.User, Boolean> checkUser = x => x.Email == Login1.UserName && x.Passphrase = Login1.Password;
Data.User u = db.Users.SingleOrDefault(checkUser);


You can use nullability to test for the presence of a record based on the LINQ query. Some source from Minima that demonstrates this is verification of the existence of a blog author:



            Func<AuthorLINQ, Boolean> authorExists = x => x.AuthorEmail == authorEmail;
authorLinq = db.Authors.SingleOrDefault(authorExists);
if (authorLinq == null)
{
throw new ArgumentException(message);
}


It's truly novel and I don't mean to make that sound like a trivial or ornamental type "novel" I write; after spending so much time building a data access layer with stored procedures and ADO.NET (Connection, Command, Reader, DataSet, ad nauseum) it seems like our collective destiny is to walk away from that and let something like a DBML data context do black magic for us.



Even though the ADO.NET Entity Framework is getting a FAIL vote from some people, I'm interested to see how this overlaps with LINQ. Even after listening to Hanselman's interview of Mike Pizzo I'm still a little unclear. My plan of action is to get serious about NHibernate to try to understand, as Scott would say, "the gestalt" of an ORM and then make the call on ADO.NET Entity Framework when it's released.



}

Thursday, July 24, 2008

Twining, TwyDL

{

A quick note that Twining isn't dead and that I actually have been working on it. Some work I've done in the past few months has involved a lot of databases I don't have more than an ISPs user/password level of access to so it's been quite handy to copy data in and out with brief pieces of code. Here's one feature I've used, exporting a table definition and all of its contents to a scripted insert statement in a file:

database(cn).table("MY_TABLE").copyto.script("c:\\temp\\MY_SCRIPT.sql")


 



Another piece that I've been working on is the ability to generate schema objects in a more fluid, compact way. I like SQL just fine but after seeing how easy it is to make data structures with the Google App Engine I sought to shoot for something similar. Also within the flow of writing a Twining script it's easy to keep this type of syntax Pythonic for certain scenarios (you want to create a temp table and dump data into it from somewhere; you want to create a table and generate sample data, etc, etc). I call it TwyDL as a play on DDL:



database(cn).create.table("Employees", 
[
col.ident("EmployeeID"),
col.string("FirstName"),
col.string("LastName"),
col.numeric("Salary")
]
)


 



The methods you see for defining column types take optional parameters so you can pass additional specifications when you feel the need. For example, the string columns default to varchar(50) but if you wanted to have a specific length all you'd need to do is:



col.string("FirstName", 25)


The same is true for numeric types:



col.numeric("Salary", 18, 4)


I've got one more thing I'm interested in implementing (time! time!) which is generating sample data given some table definition. I'm hoping to get up a rough cut of it all in the next day or two, after I've updated unit tests and organized things.



}

Monday, July 21, 2008

Reading Source, Minima II

{

Yesterday I wrote that my next stop was the use of Generics with WCF. Sometimes, it seems, a lot of experience is a handicap to learning new things - such was definitely the case when it comes to the full use of Generics with C#.  Most of my usage, I admit, has been limited to Generic Collections such as List<T> or Dictionary<T, K>.  But there is a beautiful leveraging of Generics I see with WCF that can be applied all over the place.  As a trivial example, consider the code that is used to safely read values from a database field.  I will admit to writing a lot of code like:

class ReaderHelper{
public static void GetSafeString(object field);
public static void GetSafeDecimal(object fiel);
// and so on.

}
// somewhere else in code:
string firstname = ReaderHelper.GetSafeString(rs["FirstName"]);
decimal salary = ReaderHelper.GetSafeDecimal(rs["Salary"]);


A lot of redundancy and little extensibility. Here's how a WCF infected mind might write that:



class ReaderHelper{
static T SafeField<T>(object field, T defaultValue){
return (field == DBNull.Value) ? defaultValue : (T)field;
}
}
// somewhere else in code:
string firstname = ReaderHelper.SafeField<string>(rs["FirstName"]);
decimal salary = ReaderHelper.SafeField<decimal>(rs["Salary"]);


If you coupled the above with some inversion of control you'd have a pretty powerful and extensible code for dealing with any potentially null field type coming from your database.  It's not that such use is an innovation exclusive to WCF, I see it used a lot more there.  Back to Minima, one can see a good example of this in the project responsible for exposing configuration values:



namespace Themelia.Configuration
{
public static class ConfigAccessor
{
public static T ApplicationSettings<T>(string key);
public static string ApplicationSettings(string key);
public static T ApplicationSettings<T>(string key, bool isRequired);
public static string ApplicationSettings(string key, bool isRequired);
public static string ConnectionString(string key);
}
}


 



More on Minima later (hopefully tomorrow), taking a look at database access.



}

Sunday, July 20, 2008

Reading Source, Minima I

{

I'm interested in the notion of deliberate practice as it relates to software developers.  How do we "practice" effectively?  One of the things I've been wanting to be more serious and deliberate about was reading source code.  Hanselman has inspired me with his "weekly source code" posts and since good ideas are worth copying I'll start to document some of the projects I download and look into for examples of good code.

The project I'm currently working on involves a lot of WCF. I've got mixed feelings (as well as a lot to learn) about it so I thought I'd start off by running Minima, Dave Betz's WCF/.NET 3.5 blog engine as a sample of an end-to-end application I can model my own WCF architectures after. 

Minima was not easy to get going. While I'm perhaps not the brightest kid on the block, the biggest item I struggled with would probably be a challenge to anyone: the certificates used in the WCF security model. While Betz has a blog entry documenting the basic usage of certificates with WCF, it is predicated on the WCF host not being IIS. For the blog I assumed everything should be deployed to IIS and ran into the a lesser known fact that one must use the Windows HTTP Services Certification Configuration Tool to enable the ASPNET account access to the certificates for their usage. There were also a couple of post build events in the project that I removed after getting my references set up.

But before I get into particulars, I wanted to go over the broader structure of the project.  The Minima solution has the following projects:
* Minima.Service
This has the service and data contracts with no implementation
* Minima.ServiceImpl
This has the implementation of the service
* Minima.Configuration
A configuration helper which makes use of a library called Themelia (Betz is, apparently, a Biblical Greek scholar on the side)
* Minima.Web
Library for the blog website's features
* Website
A website project
* Website Service project (exposes services for posting content to the database via WCF)

I'll write about more particulars in my next post but for this overview my biggest takeaway in the project structure is decoupling.  Separating the service from the service implementation, separating the website from it's functionality by a project with the only purpose of implementing that backend logic, and separating general purpose frameworks like Themelia (for reading the config file etc).

When I start my own projects I usually think too much about doing a proof of concept and less about decoupling the overall structure. As a result most projects start off as a "sketch" in a single Visual Studio project and by the first release end up staying that way on a permanent basis. But perhaps what we should focus on as programmers is less the cleverest algorithms and more the most elegant structure for building solid applications.

Next stop: WCF and Generics.

}

Wednesday, July 16, 2008

Tragically Well Known

{

Of late there seem to be a lot of the well knowns of blogging bowing out (at least in volume) because of how much work it takes to qualify and disclaim the topics they take upon themselves. I find it sad because even the essays I find myself disagreeing with usually provide the same thought provoking effect as the ones I enjoy in agreement. It's strange to think that people like Paul Graham and Joel Spolsky would be exasperated by the barbs people toss their way and yet, it seems, they are.  Paul's essay on disagreement seems evidence of this and the most recent Stackoverflow podcast dwells considerably on the topic from Joel's perspective.

I would like to make the following proposal both in encouragement of people like this writing and for people like myself enjoying it: rather than quick barbs and/or "jumped the shark" posts, return to the previous material of the author and enjoy an old post. It's not that disagreement is bad or unwelcome; I think a lot of the well knowns enjoy a spirited discourse.  It has more to do with people either misunderstanding or disagreeing in the wrong way - DH0 to DH4 as Paul would have it.

}

Sunday, July 13, 2008

Predictably Irrational: Startups and Open Source

{

The Herding Code podcast took up the topic: "Why don't startups run on Microsoft?" which I thought was interesting - it crossed paths with comments in a spat I've followed between Atwood (who chose .NET as a platform for Stackoverflow) and Marco Arment (of tumblr fame (side note: I actually have a tumblr)).  Had you asked me before Friday for an opinion I would have probably attributed it to the Byzantine licensing schemes for Microsoft products as well as marketing oriented decisions like making IIS 7 unavailable on XP. 

On Friday, however, I heard a commentary on Marketplace from Dan Ariely that is a basis for a hypothesis that hadn't occurred to me but seems to make perfect sense for software.  Ariely, a behavioral economist at MIT, starts with suggesting that the next time you eat out with friends, it might be better to have one person pick up the "pain of paying" for dinner rather than distributing it across all the people who were out. According to the commentary (emphasis mine):

Findings from behavioral economics tell us that one person should pay the entire bill and that the person paying should alternate over time. When we pay any amount of money, we feel some psychological pain. We call this the pain of paying. This is the unpleasantness that is associated with forking over our hard earned cash. But it also turns out that this pain does not increase linearly with the cost of the meal. This means that when we double the payment, the pain doesn't double; it increases just by a bit. In fact, the biggest increase in the pain of paying comes when we switch from paying nothing to paying something. Now, it's easy to see why one person should pay the entire bill. How so? Well, if every person paid their share, they would all experience some pain of paying.

If you're curious about how Ariely is able to make that assertion, he elaborates on this and other ideas in his book Predictably Irrational.

It makes perfect sense that this could be a credible idea behind why startups don't work with Microsoft technology - that the cost is less of a factor than "costing" some dollar amount.  If you attach to that complex licensing and many flavors of the same product and you get pain that goes beyond the "pain of paying."

It makes some sense on the Microsoft side of things too; rather than trying to determine which products developers should get matched to, most companies just buy a high end MSDN subscription for developers even though chances are high that not all the products are actually used.  They can count on "enterprise" companies conservatively overpaying and hence getting the most out of them.

A couple of thoughts that come to mind:
1. How could one go about trying to measure the "pain of paying" with software?
2. Does "free" open source translate to more time in managability/expertise?

}

Friday, June 27, 2008

Change Dispensed

{

Steve posted a coding challenge a few days ago - a change dispenser. I thought it would be a nice exercise for my fledgling Python skills and implemented it with just a small variation on pluralizing coin denominations.

def make_change(amt):
output = "Change is "
coins = (['quarte|r|rs', 25], ['dim|e|es', 10], ['nicke|l|ls', 5], ['penn|y|ies',1])
for i in coins:
r = amt // i[1]
if(r > 0):
coinout = re.split('\|', i[0])
output += "%d %s%s " % (r, coinout[0], coinout[1:][r > 1])
amt = amt - (r * i[1])
print output

make_change(48)




A few things I learned along the way:


* I was reminded that dictionary objects do not guarantee order.


* I was using Python regular expressions to do a match on the string "this |and|or that" and discovered if you use match with simply \|(\w+) it returns nothing since the match must start from the beginning of the string!


* I was going to use a lambda expression for the pluralization but that's such a large hammer for what in the end would become a split



Python's behavior with booleans is another point of interest - when I test the following: coinout[1:][r > 1] I'm taking advantage of anything true being a 1. I wonder if this is "bad" but it's a seductive thing to take advantage of...



}

Monday, June 23, 2008

Deep Fried Bytes, Yegge, Interviewing

{

Found a good podcast today, "Deep Fried Bytes." Skip the first episode but the second on interviewing is a gem. Although it was posted on May 29, it ties in quite well with thoughts delivered (not simply written, but delivered) by Steve Yegge in his recent post on finding good people, Done and Gets Things Smart. Not only is it entertaining to hear Ayende Rahein take nonusers of using blocks to task, but later Scott Belware seems to be on the same page as Yegge on how you can know if people are "good."  Here is his approach (listen to the podcast if you want total accuracy):

- I don't ask questions I do pair programming for interviews...
- Interview questions are irrelevent... most of the people asking interview questions are showing the people who are interviewing what they know
- Ask for a code sample with unit tests that run inside Visual Studio
- If that's okay ask them to come in for 4 hours of pair programming
- Most interview related items would come up during the pair programming session

}

Thursday, June 12, 2008

C# Multiple Replace Extension Methods, Levithan Style

{

A couple of nights ago I blogged about an implementation of a technique to replace multiple patterns in a string on a single pass. Steve Levithan had an entry on the approach (not mine in specific, just the approach and commenting on a few weaknesses). It inspired a few things out of me: first, making the multiple replace an extension method of the string class, and second to duplicate Steve's approach which enables a more robust model because you can use metasequences etc...

Here is the code (included the using statement since the use of ToArray() from the Dictionary key collection isn't available without System.Linq):

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

static class RegexExtender {
public static string MultiReplace(this string target, Dictionary replacementDictionary) {
return Regex.Replace(target,
"(" + String.Join("|", replacementDictionary.Keys.ToArray()) + ")",
delegate(Match m) { return replacementDictionary[m.Value]; }
);
}

public static string LevithansMultiReplace(this string target, Dictionary replacementDictionary)
{
foreach (string key in replacementDictionary.Keys) {
Regex r = new Regex(key, RegexOptions.None);
target = r.Replace(target, replacementDictionary[key]);
}
return target;
}

}


Here is some usage:




// the original approach, as an extension method
string x = "Holly was a hunter";
Dictionary rdict = new Dictionary();
rdict.Add("Holly", "Hannah");
rdict.Add("hunter", "hatter");
Console.WriteLine(x.MultiReplace(rdict));

// Steve's technique
rdict = new Dictionary();
rdict.Add(@"[A-z]", "x");
rdict.Add(@"\d", "y");
string test = "David is 33";
Console.WriteLine(test.LevithansMultiReplace(rdict));




}

Tuesday, June 10, 2008

Regex: replace multiple strings in a single pass with C#

{

I wish I could say I was the clever one to think of this but I ran into it in my copy of the Python Cookbook (the original author is Xavier Defrang, the Python implementation here). It's cool enough that I ported it today - I'll know I'll use the C# implementation of it quite often:

        static string MultipleReplace(string text, Dictionary replacements) {
return Regex.Replace(text,
"(" + String.Join("|", adict.Keys.ToArray()) + ")",
delegate(Match m) { return replacements[m.Value]; }
);
}
// somewhere else in code
string temp = "Jonathan Smith is a developer";
adict.Add("Jonathan", "David");
adict.Add("Smith", "Seruyange");
string rep = MultipleReplace(temp, adict);


}

Sunday, June 08, 2008

Languages And Thinking

{

I'm approaching the end to a rough week and should be coding but the virus scanner on my office machine is slowing development to a point where it's not bearable for me.  I'll pass the time with a quick thought about how programming languages affect thinking and why it makes me both picky about languages I use and also curious to see how the different languages solve problems.

I will confess that the project I've been working on is written in VB.NET.  The reason for that was very practical since our client was adept at VBA and needed to, on occasion, get to the code level of things.  I'd spent a lot of time in Visual Basic (the "classical" VB) so I thought nothing of it - perhaps somewhat of a refreshment after so many years away.  As we wrote more and more code, I started noticing a lot of nested "If" statements in the style of:

If Some Condition Then
If SomeOtherCondition Then
If YetAnotherCondition Then


You get the picture.



I remember working with a different VB programmer and she was also given to writing a lot of nested conditions in the same manner even though we were using C#:



if(cond){
if(cond2){
if(cond3){


At the time it really bothered me in a "code smell" sort of way; nesting conditions, I would have argued, invites clutter and entropy. Since I've been attending Hanselman University for a while now I can say with more technical gravitas that they increase cyclomatic complexity and this was why they smelled bad. The alternative I would have wished for would have been:



if(cond && cond2 && cond3){
...
}


Pretty natural, right?  Actually no, especially if you're coming from Visual Basic because the Visual Basic And and Or operators don't do short circuit evaluation.  If you combine boolean expressions you have to make a mental note to verify that they both will work at runtime - that there is no dependency between them.  That's something a C# progammer completely takes for granted often writing code like this which is a ticking bomb in VB.NET (it won't go off until you're demonstrating the app to your client, trust me):



If Not MyCollection Is Nothing And MyCollection(0) = "Something" Then
...


One expects the second expression will be passed if the first fails in a "short circuit" approach. Unfortunately, Visual Basic .NET will attempt to evaluate the second even if the first is not true!



To clean this all up the VB.NET folks provided the AndAlso and OrElse operators which do traditional short circuit evaluation. I read somewhere that the reason And and Or were left as is was for backward compatibility and people who were "upgrading" their code from Visual Basic to Visual Basic.NET. Using these operators you're back to thinking "normally" as a C#, C, Javascript, etc... developer.



So back to my original thought - nested If blocks are a simple way around an operator that doesn't short circuit and it's a way of thinking if you've spent a lot of time writing Visual Basic code. The language is what drives that even though there may be alternatives. Even though it may produce cyclomatic complexity. Some people tell me picking a language is just a simple process of picking a tool, but I think it's more than that; it's picking a way of thinking. That's why it's not only important to me, it's interesting to see how different languages lead us in different directions. Even if an idiom is available elsewhere, it's getting to think that way that is most often  the trick to being better in both languages.



One more side note, I can chart a few different ways in which new languages have affected me. Take a look at the type of thing I did before a lot:



foreach(string s in stuff){	
master += s + ",";
}
master = master.Substring(0, master.Length -1);


Nowadays:



// like a map, I first started thinking this way from perl
stuff.ForEach(delegate(string s) { master += s + ","; });
// like a join, very Pythonic
String.Join(",", stuff.ToArray())


}

Sunday, June 01, 2008

Galloway et. al. Roundtable Podcast

{

If you haven't and you do Microsoft development, give an ear to John Galloway, K. Scott Allen, Scott Koon, and Keven Dente in their "Technology Roundtable" podcast.  There are a lot of podcasts I find entertaining, (like Joel and Jeff's discussions) but these guys seem to do what I do - and to contextualize that since it may sound presumptuous, they deal with Microsoft development tools building "real world" software.  

I try to have "take aways" from podcasts so from the first more impetus to investigate Ninject and dependency injection as well as more investigation of LINQ to SQL and the ADO.NET Entity framework (opinions flew on these, I'd like to develop some of my own).  Finally, even though I'll probably skip the beta, I will look forward to .NET 3.5 SP1 since ASP.NET Dynamic Data will be packaged therein.

The second podcast had a great discussion on javascript libraries. I've used jQuery and YUI and Prototype on different projects and while my fondness for Prototype/Scriptaculous is probably greatest of all I am always eager to hear other people's experiences. The framework I have yet to do anything serious with is Dojo - I did some quick prototyping of their flyout menu with ASP.NET server code and I hate to say it but the ASP.NET Menu control was a lot more effective and fast. While it wasn't explicitly stated, this podcast has dampened my interest for the ASP.NET Ajax stuff - I looked at it again a few weeks ago and it seemed so... heavy.  I'm not sure who mentioned it in the podcast but they said it seemed more oriented for writing controls versus Ajaxy type applications.  I would have to concur with my limited knowledge.

I'll stay tuned, it will be interesting to see what they talk about next time.

}

Saturday, May 31, 2008

Knowing C

{

I've been having a good time listening to the StackOverflow podcasts. Joel's a great curmudgeon and Atwood is as opinionated as ever.  An ongoing disagreement between the two has been the usefulness of knowing C.  Joel's adamant about its importance and Atwood thinks there is much else a developer can spend their time in understanding. 

Eric Sink has since chimed in with a post called C and Morse Code wherein he reveals his cards: like Joel, he thinks it's of vital importance if you want to reach past mediocrity:

I'm not going to take a black-and-white stance on this.  I won't go so far as to say that every developer must learn C.  I've met lots of developers without C experience who are successful and making positive contributions to important software projects.

Furthermore, I'll admit that knowing C is not a magic solution to poor skills.  A lousy developer who happens to know C is simply better equipped to hurt himself or somebody nearby.

However, I can say these two things:

  1. All of the truly extraordinary developers I know are people who really understand the kind of low-level details that C forces you to know.
  2. Every programmer without C experience has a clear path of personal development:  Learn C.  Get some real experience using C to write a serious piece of software.  Even if you never use it again, you'll be a better programmer when you're done.

My relationship with C is tenuous at best. I spent a few months some years ago delving into it (and C++) seriously - I'm curious to go back and find some of that code but it was a few machines ago*.  I remember during that time I'd work on little toy programs (mostly an implementation of some algorithm) in C and then have the need for a utility and write it in something else.  It would be interesting to take Eric up on his second point of writing a "serious piece of software" using the language.  One interesting angle on this is how one would keep said "serious piece of software" strictly in the realm of C, without venturing too much into the world of C++ and object orientation done poorly.

So brainstorm question: what's something nice and useful that could be implemented strictly within C? (That one might not yawn and think *gosh* that would take 1 minute to do in Python).

}


*Great memories of Me, Markus, and bcc32 in a coffee house somewhere in southern California.  Too far gone are those days...