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())


}

No comments: