Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, December 04, 2005

Writing Clear Code

This topic is a bit of a divergence from Custom Actions, but useful for some general coding skills. I'm going to highlight the C# language in this post, although you don't need to know C# to benefit from this discussion - I'll cover the essentials in the post. The topic is how to write clear code that makes it easier to defer the understand the intention of the code rather than the behavior of the code. The subject came up about a few months ago in a discussion with a coworker who initially didn't quite agree with me. I'll lay out the argument here as I did with him.

Take for instance the following code snippet:

string a = "hello";
string b = "hello";
System.Console.WriteLine(a == b);
System.Console.WriteLine((object)a == (object)b);
Lets explore the last two lines. The a == b equivalence operator is working on strings, and by C# rule, two strings are equivalent if they are both null, or if both values are non-null references to string instances that have identical lengths and identical characters in each character position. Translation - two nulls are identical, and any two strings that match, case sensitive, will result in a true expression. In the latter comparison, when we cast both of the strings to objects, we are not comparing the values of the strings, but the objects themselves.

What do you think it will print? The answer is True and True. Why? String literals that are identical within the same assembly refer to the same instance. Translated, 'a' and 'b' are variables that refer to the same underlying object.

Now lets replace the declaration and assignment for string b with:
string b = "he"+"llo";
Now what do you think it will print? The answer is again True and True. Why? Because the Lexical analysis (lexer) in the compiler stripped out the needless additive operator in the literal. The same would have happened if we changed the string to be "hell\u006f" - since '\u006f' is the Unicode escape sequence of the lower-case letter 'o', and this expansion takes place (most likely) prior to the lexer during the transformation phase in the compilation process.

Now lets replace the same line as above with the following two lines:
string b = "he";
b += "llo";
Now what do you think it will print? The answer is now True and False. Why? The strings are equivalent, but since the preprocessing of the source file before the compilation did not identify the strings as being the same literal, they are in different objects. In fact, because a string is immutable (once created cannot be changed), there was the construction of the string "b" during declaration and initial assignment that was later garbage collected when a new instance of "b" was created during the string concatenation.

Now that the necessary background information is understood, can you tell me the intention of the following code snippet?
string a,b;
//code here that assigns and manipulates a and b
...
if (a==b)
compareOK();
else
compareBad();
I'm hoping you are going to tell me that you have no clue as to the intent of the programmer. The intent could have been to compare the two strings in a case sensitive manner, ignoring cultural rules (which is what actually is happening in the above snippet). It also could have been to compare object equivalence, just that the programmer forgot to cast the strings to object first. The intention could also have been a case-insensitive comparison. Another possible intent was to compare strings using cultural rules. The intent of the programmer simply is not clear!

Rewriting the comparison line in the above snippet correctly, assuming the actual behavior of the code was the intent should look like this:
if ( String.Compare(a, b, false,
System.Globalization.CultureInfo.InvariantCulture ) == 0 )
This tells me that the intent of the programmer was to compare the two strings in a case sensitive manner, ignoring cultural rules . There is no other possible intent given the above line of code. This is not saying that the code is correct - just that the intent of the code is clear to those lucky enough to read it, and that the developer thought it through.

If I am skimming through some code and see a non-String.Compare() string comparison, I will sprinkle a //BUGBUG: comment above it. Why? The simple string comparison syntax has been a rather common cause of bugs in C# code - much like the C/C++ switch statement. When investigating an issue in a piece of code, I will first look for these BUGBUG's and the TODO's as a starting point - often with better-than-random chance results.

Thursday, November 11, 2004

.NET Threading

Although my blog states I'd be covering some C# stuff, I haven't posted anything related to it. Time for that to change:)

I've been fighting with threading in a C# .NET application. Perhaps my frustration was related to the poor coverage of threading in pretty much any .NET book. Perhaps it was because MSDN doesn't really have a decent overview or "related links" in any of the threading-related topics. Another guess is that .NET is dissimilar to Java in its threading mechanism. Most likely, I have been spoiled by Win32's richness and capability when it came to threading.

I uncovered an excellent link to "Multi-threading in .NET" It is currently in 2nd place on a Google search for that term. I am using my limited "Google karma" to help pump that resource to #1 - the article is that good. Newbies to the .NET framework will not be overwhelmed, and moderately experienced .Net'ers will not be bored by it. It simply takes everything about threading and puts it into one place with some great examples. There is a slight C# bent to it. The article contains some .NET 2.0 items, and appears to be regularly updated. One thing I would change - it would be nice to have a "what's new" section for repeat visitors. Jon has plenty of other .NET related articles from his C# page. I haven't read anything else by him yet, but I'm assuming the quality bar is nearly the same.

Some favorite quotes: "...writing thread-safe code is all about taking luck out of the equation." Relating to changing Form or Control elements from a different thread than what they were created on: "You may get away with it in some cases, but only by blind luck."

Friday, October 29, 2004

Joel's best articles reviewed

Even though I have a billion other things to do, I couldn't help but get sucked into reading every one of the 112 (as of this writing) articled submitted to Joel's best articles on Software Development. This is a deviation from my normal content, but there is value to be gained for most all readers in the Software industry - designers, marketers, and developers.

Here are my favorites (not necessarily the best of the bunch, but ones that got me to think), I will link to the nomination post, suggest the audience type, and give my .02c. :

Church of XML. If you use XML and like sarcastic humor, this may interest you. At least, I hope it is meant to be sarcastic. XML is great for some things, but it is not the holy grail solution for everything data related. I remember in Y2k working for a company whose directors told the development staff that we must use XML. We quickly coined the phrase "buzzword compliance" to describe the requirement. There was no possible use for XML data in our application where XML was a viable alternative, much less a better one. At a later company, the value of XML as a method of integration with our customer's systems and as a communications mechanism (XML-RPC) was profoundly positive. Members of the Church of XML may want to defect after reading another few nominated articles: ant and XML, and Soapbox: Humans should not have to grok XML.

How many Microsoft Employees Does It Take to Change a Lightbulb. Any developer should enjoy it, but managers (especially ones driving deadlines) need to read it. I am a big fan of Eric Lippert's writing style. This one delves into the cost of fixing a bug. I prefer this one to the main article nominated since it is more to the point. Setup developers may want to read The anatomy of a bug as it deals with an uninstallation issue, and something you may want to think about. Both articles do not mention the cost of fixing a bug in terms of dollars (refer to your copy of Code Complete for more on this). Although you may disagree with Eric's line: "At Microsoft we try very, very hard to not release half-baked software," the point he is trying to make is if you do release bad code, it costs a bunch (in dollars and manpower) to fix it later. Almost on-topic is a 20 minute video of an actual bug triage meeting at Microsoft. Good stuff.

Plus ca change. Reading for anyone interested in how standards can be used to even the playing field for small software vendors. Or perhaps not. While I am not heavy into the web standards discussions today, at one point I was. To quote The Gunslinger, "The world has moved on." HTML's initial purpose (IMHO) was to allow me (the user) to render content as I (the user) wanted to see it. Netscape and Microsoft decided that their extensions to HTML would be the differentiators between their browser products. The content producers decided that web content should be shown to the user the way the content producer wants it to look, and with these extensions, they could. This seriously limits the accessibility of the content for people with disabilities, which was one characteristic HTML was supposed to give content producers (and users) for free. Flash and Shockwave further limited the control of content by the user. My thoughts on this today are for vendors to add their extensions whenever they want. If the extension provides enough value, other vendors will pick up on it and it will become a defacto standard. Today, implementing a standard in a web browser is not good enough to get you lined up at the starting gate. Look at Internet Explorer - massive share and not 100% compliant.

Lean Construction. Audience is general developers interested in planning. If you have read Code Complete, you will notice the use of metaphors throughout, one of which likens software development to a construction project. This article is the result of a software developer attending a class for construction foreman related to project planning. Some of the takeaways trumpet agile development methodologies. I especially like the quote: "master schedules are useless for planning work, contracting practices create islands of optimization, and there are large opportunities for productivity improvement." Is the author referring to current software development methodologies or old construction planning?

The 5 Pitfalls of Estimating a Software Project. Also see "Repeat After Me: I Am Not In the Software Business" in the same nomination. Everyone should read these. I have nothing else to add - they both have excellent points and are short enough to easily grasp it.

In the Spirit of C. Hardcore programmers. This one is fantastic. In the "managed" world of programming frameworks, it is easy to lose important roots in development. I am completely surprised by the number of programmers that do not know C or C++ well enough to code a real application. I've found that the best programmers are ones with roots in C. C developers tend to be able to learn new languages quickly, and pick the best language for any given programming task. Noteworthy quote: "In my experience there is almost no limit to the damage that a sufficiently ingenious fool can do with C++. But there is also almost no limit to the degree of complexity that a skillful library designer can hide behind a simple, safe, and elegant C++ interface. "

Ten Ways to Kill Design. Product managers are a good audience. This talks about new designs and pilots, and how/why they fail (unrelated to the design itself). For more information on the design, spec, and requirements, please check out another nominee On Reqs and Specs.

Hazards of Hiring. For anyone considering beefing up your workforce or looking for a job. It is an Eric Sink article that is very good, as usual. There are more worth reading that are related, such as programmers are not hackers.

Simple is Beautiful. All developers. Quote: "If you manage to write some code that a non-programmer can more or less understand, then you know you're there. The code should be simple and self-explanatory enough that should be a breeze to refactor in the future." Another nice quote is from Brian Kernighan (an inventor of C). I have this quote hanging up by my desk: "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."

We built it but no one came. Product Designers. Quote: "the thing that engineers love most about their technology is precisely what prevents them from making money." I looked at Steve Johnson's blog and he writes lots of great stuff in the development/marketing arena. Subscribed! I recommend anyone in the position of designing a product for the Average Joe to pick up a book Crossing The Chasm by Geoffrey Moore.

Growing, Pruning, spiking an architecture. Designers. Quote:"Good architectures are those in which it is considered easy to create the features desired."

What is a Web Service. Anyone. I agree with the other commentator. This is more of a definition, but summed up well. This allows me to segue into the topic of dynamic vs. loose coupling in typical service oriented architecture, although this latter link is more specific to architects.

Exceptions vs. Status Returns. Developers. The age old debate on the use of Exceptions. My position is contrary to the nominee. If you take the debate further, there is the use of exceptions as flow control. Exceptions are good when used appropriately - for the exceptional case. Too many times I have seen code that encourages or uses exceptions when simply returning a status value would be better. There are some good examples here. An OutOfMemoryException is a valid use of an exception. No matter how deep in my code I am, this is something that is highly unlikely to be handled appropriately or anticipated.

How to tell your personality from your code. Developers. Quote: The Obfuscator: "while(*a) *b++ = (islower(*a))? *a++:*a++ + ('a'-'A');" I have not only worked with each of these coding personality types, but I have been them. I wonder what my code personality type was today?

Choose your competition. Entrepreneurs. Quote: "The existence of a competitor indicates the existence of paying customers." As usual, good stuff from Eric Sink.

State of Affairs in Computer Science Education. Everyone. I was going to write a blog entry about this one. Since I'm trying to get a new sheepskin, one of the classes I am required to take uses a book "Object-Oriented Application Development using Visual Basic .NET" by E. Reed Doke. The book stinks. The fact that I must take and pay for this "capstone" course instead of one where I could actually learn something new is one problem with the system. In this book, the author uses a phone number as the primary key on the Customer table! I guess with phone number portability, this is an acceptable PK! We are teaching people this? The brilliant author creates a method in the Customer class called TellAboutSelf() that returns a string representation of the object. Wouldn't it be industry-standard and expected to override Object.toString()? WTF! This simply adds to the retraining requirement of new grads that enter the workplace. This is another segue into yet another nominee Eric Lippert's Cargo Cult Series. If you are a new or experienced developer, and especially if you are still held captive by academia, this series is a must-read.