Friday, April 13, 2007

Painful to Read

I recently discovered a new (to me) blog, which you've probably been reading for a long time.  But if you haven't been reading Worse than Failure, you ought to be.  It's nice to be able to look at someone else's code now and then and say "I can't believe someone would do that!"

#    11:24 AM by Nick | 1 Comment |
 Thursday, April 12, 2007

More Things Visual Basic Left Out

I mentioned last week about how Nullable Types weren't really in Visual Basic.  You know what's also not there?  Iterators. No Yield statement.  Since I often times have to switch between C# and Visual Basic, I find these differences to be quite frustrating at times.  I really wish Microsoft would do a better job of maintaining parity of features between the various .NET languages they support.

#    9:32 PM by Nick | 1 Comment |
 Monday, April 02, 2007

Nullable Types Not Quite There

Lately I've finally been working with Visual Studio 2005 and .NET 2.0.  Previous to this, I'd been working with 2003 and 1.1 almost entirely, and only read about (though extensively) and played with 2.0.  Since I only play with C#, I got used to all the new features it added, and wrongly assumed that Visual Basic .NET brought the same features to the table.

As I should know by now... that was a poor assumption.  I found this out today when I was trying to use Nullable types to deal with database access.  I've been working with VB most recently, so I created an empty playground project to play with the features and see how they worked.  Then I realized I had no idea how to declare a Nullable type in Visual Basic.  I'd only done it in C#.  That's no problem... a minute later I had written this sample code:

Dim n As Nullable(Of Integer)
Dim m As Nullable(Of Integer)

n = 7
m = 3

Console.WriteLine(n + m)

Hmmm... Nullable(Of Integer) isn't nearly as nice looking as int?, but VB syntax has always been more bulky to me than C#?  Hold on a second!  Why doesn't that last line compile?  Doesn't VB.NET have the same type coercion features of C# for nullable types?  That would be a definite no.

For the record, here is the identical code in C#:

int? n = 7;
int? m = 3;

Console.WriteLine( n + m );

Now then... doesn't that look nice?  And it compiles and works like you'd expect it to also.  Is that so much to ask?  So the reality is that Visual Basic only supports Nullable types because it happens to be implemented using Generics in the CLR, so Visual Basic didn't do any extra work to support them... bare bones.  But that's all you get.  Just bare bones support without any of the extra niceties that you'd expect to find.

#    8:59 PM by Nick | No Comments |
 Tuesday, March 27, 2007

If You're Lucky It Will Blow Up

In my tenure as a software engineer, I've seen a lot of poorly written code, especially in my C++ days.  Pointer magic that had no business being compiled, and error handling that was slim to non-existent.  Even in the world of .NET, it's still possibly to write dangerous code:

try
{
   // Call a method may throw an exception
}
catch ( Exception ex )
{
   // Eat the exception
   System.Diagnostics.Debug.WriteLine( ex.Message );
}

How many times have you seen code like that?  Hell, sometimes I don't even see the Debug.WriteLine.  Sometimes they just eat the exception.  Exceptions aren't a bad thing.  In fact, having an exception occur is a good thing.  I still remember something my advisor said during a class talking about pointers at MSOE... "If you're lucky, it will blow up."

The worst errors that can occur are the ones that don't have outward signs.  Perhaps you did some bad pointer arithmetic, but instead of throwing an exception because you illegally accessed memory, it simply reads that memory and a counter equals 50 instead of 5.  Your program could appear to function perfectly, but will provide incorrect results.  Worse yet, when an symptom does finally appear... the symptom will so far away from the cause, that you may never find it.

Eating exceptions is about the closest you can come in .NET without trying really hard.  People are so afraid of seeing a box with that red X, that they eat them left and right without realizing that having an immediately failure that is easy to identify and fix is preferable to a bug that is impossible to track down.

Exceptions happen for a reason... and that reason should be taken seriously.  If you can write code to handle that exception in a catch block, then by all means do it.  But if your "exception handling" code simply boils down to logging it and continuing... do yourself a favor and rethrow that exception (or don't catch it at all) and put your program out of its' misery.  You'll thank me in the long run.

#    8:49 PM by Nick | No Comments |
 Thursday, March 22, 2007

Why Case Insensitivity Blows

I ran into this problem at work today, which reminded me why case insensitive languages (like Visual Basic) suck.  Or if you prefer, I found a bug in a Microsoft tool.  I was using xsd.exe to generate a type safe class for an XML schema that I received from a company we do business with.  Instead of reproducing all the schema and code here, I'll boil it down to the simplest code which still reproduces the problem.  Let's say you have an XML schema that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Node">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="VALUE" type="xs:string" use="required" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

And here is an XML fragment which will obey this schema:

<?xml version="1.0" encoding="utf-8" ?>
<Root>
  <Node VALUE="Hello">World</Node>
</Root>

Pretty simple so far, right?  If you save that schema off as XmlDoc.xsd, and then run xsd against it using the following command line options:

xsd XmlDoc.xsd /c /f /l:VB

You will get the following class definition as output:

'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'     Runtime Version:2.0.50727.42
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On

Imports System.Xml.Serialization

'
'This source code was auto-generated by xsd, Version=2.0.50727.42.
'

'''<remarks/>
<System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42"),  _
 System.SerializableAttribute(),  _
 System.Diagnostics.DebuggerStepThroughAttribute(),  _
 System.ComponentModel.DesignerCategoryAttribute("code"),  _
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=true),  _
 System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=false)>  _
Partial Public Class Root
    
    '''<remarks/>
    Public Node As RootNode
End Class

'''<remarks/>
<System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42"),  _
 System.SerializableAttribute(),  _
 System.Diagnostics.DebuggerStepThroughAttribute(),  _
 System.ComponentModel.DesignerCategoryAttribute("code"),  _
 System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=true)>  _
Partial Public Class RootNode
    
    '''<remarks/>
    <System.Xml.Serialization.XmlAttributeAttribute()>  _
    Public VALUE As String
    
    '''<remarks/>
    <System.Xml.Serialization.XmlTextAttribute()>  _
    Public Value As String
End Class

What you'll notice is that that RootNode class has two fields named Value.  One of them is upper case (as it was in the schema declaration), and the other is Pascal case.  This second one is marked with the XmlTextAttribute, meaning that it is the property which represents the Element Text value (in my sample XML document it would be equal to "World" while VALUE would equal "Hello").

If we were doing this in C#, all would be fine and dandy since it's case sensitve.  However, with Visual Basic, this generates a compiler error.  In the case of my 1300 line schema file at work, I had to modify 42 different fields that met this pattern.  And because I had to hand modify an auto-generated file, there is no way that I can automate this generation as part of a build process... which sucks if the schema ever changes.

Wouldn't it be nice if xsd.exe were actually smart enough to verify that there was no name collision with the Value field before it used it, and chose an alternate name... or perhaps had a command line argument were you could provide a name to override the default?

#    7:54 PM by Nick | 4 Comments |
 Tuesday, March 20, 2007

What Do You Mean You've Never Seen It?

It always amazes me when I run into people in the software profession that haven't seen Office Space.  So I was totally shocked when I found out that not only has the person sitting to my right never seen it, but neither has the person on my left at my new client.  It's required viewing!  I immediately had to bring in my copy of the DVD for them in order to rectify the situation.  I also always make sure to warn anyone who hasn't seen it, that it's not a comedy.  It's a documentary.

#    9:29 PM by Nick | No Comments |
 Sunday, March 18, 2007

Give Away Your Old Computers

I blogged about this about two months ago, but it bears repeating.  Developers always make sure to have the best computers, and we upgrade often.  After all... it's our job to stay up to date, and as geeks we always like to have the best toys.  But what do you do with your old machines once you've decided it's too out of date for you?  Odds are that even though it's out of date to you, it's still a pretty good machine for someone else.

I just did this with my old laptop, and I've done it a few times before.  Don't sell your old computers on eBay.  Find someone who needs a computer and can't afford one, and give it away.  It won't take you long to format the drive and put a fresh install of Windows on it.  Now your computer can have a good hardy second life.  Odds are that it will have a more useful life than with someone who buys it on eBay just to scrap it for parts.

In one case, an old computer I gave away was lucky enough to have a third life.  After the person I gave it to was able to get something better, she asked me whether I wanted it back.  I laughed, and told her to find someone to give it away to.  And so it went on to serve yet another master to someone who needed a computer at a key time in her life.  My only regret at the time was not having something better to give away myself so she could have something better than a third generation hand me down.

It feels good to do, and it's something that we as developers can easily do.

#    12:35 PM by Nick | 1 Comment |
 Monday, March 12, 2007

Funny Code of the Day

If vdResult.IsValid = True Then

I have no idea what you'd want to do if that happened.

#    7:09 PM by Nick | No Comments |
 Friday, March 09, 2007

It's Like Watching a Car Accident

You just can't stop watching... even if it is 10 minutes long.  So let me get this straight... voice recognition is supposed to make things easier... right?

Via Omar.

#    6:10 PM by Nick | No Comments |