Friday, November 09, 2007

Shades of Laziness

I'm currently maintaining an EOL system. As soon as I found out that the system was EOL, my development approach took a 180 degree turn. No longer do I have to think of the long term ramifications of my code. I no longer have any reason to refactor. Indeed, I would be irresponsible to do so since refactoring always comes with the risk of introducing new bugs and I would be adding to the workload of the business analysts (who are also the QA engineers) since they are doing the double duty of working with this old system and transitioning to the new.
I even came across some support for my position after the fact (see "Delaying Development Expense").

So now I'm free to be a lazy developer: throw code in the UI layer, add small hacks where I would usually refactor to allow for proper addition of new functionality; simply do the quickest, easiest thing. It's amazing how much less time this requires than "proper" development. Of course, if the system were to stick around, ever more time would be required. This kind of lazy is different than the good kind of laziness in a developer; I've traded one lazy for another.

One thing that is actually liberating is the fact that I no longer groan at all the ancient bad architecture in the system that I formerly had to work around. Architecture is completely irrelevant; no given architecture is better than another at this stage - it's no longer a beast that I must fight.

Liberating though it may be, I think I'd rather have my old lazy back.

Wednesday, October 31, 2007

Fun with Scheme

As I've come across the time, I've watched some of the videos (and read the book) of "Structure and Interpretation of Computer Programs."

I've been using Petite Chez Scheme along with Textpad for my little learning exercises (some of the other implementations of Scheme seemed rather difficult to get working on windows).

It's amazing how little there is in common between programming with a lisp language and mainstream object oriented code monkeying. Sure, C# has anonymous methods, but the fact that they're available doesn't change much (although who knows how far the DLR will take mainstream .Net developers down the dynamic language path).

In one of the first lectures, Gerald Jay Sussman challenges the students to come up with an iterative rather than the commonly taught recursive solution to the famous "towers of hanoi" puzzle. It turned out to be quite a little challenge for me; both discovering the algorithm and translating it into code the Scheme way.

The first thing that I had to struggle with was (of course) all the parens. Absolutely everything is inside pairs of parentheses. I don't really understand the exact reason for this (it somehow enables easy creation of programs using declarative data), but one thing is for sure - it's really easy to learn the syntax of the language (and there isn't a ton of crazy tricks as in C++ whereby on might use the language for years before discovering some). Making sure your paren pairs are matched up takes a bit of effort. It seemed like I needed to transform into a human compiler in order to write a function with much length, but after awhile it's not so bad. Conforming to the indenting conventions makes it easier, but it sure seems to make it difficult to cut and paste code or insert a comment at the right spot.

The next thing that threw me was the fact that there are no reference parameters in Scheme; they are always by value. At one point I was searching all around trying to figure out how to pass parameters by reference, and couldn't find a way before I finally figured out that there is no way. I'm pretty sure it's purposeful: functions produce no side effects.

The last main hurdle to overcome is the fact that you're not supposed to declare and set variables as a rule. Hell, you can't pass the suckers to functions, so what's the point anyway? I learned that one the hard way. I created my entire program (managing to test each function as I went along) only to discover that the last link was impossible. My practice of using variables in the mainstream way painted me into a corner. Instead of declaring variables, you create let blocks with the variable's value declared at the beginning of the block. The language help says that let blocks are just another form of lambdas which is pretty cool (everything is functional).

Here was the easy part: using lists. There are some funky things about lists that I don't quite understand, but one thing was easy: stuffing whatever I wanted in there. I wanted a string to represent the name of each tower to be stored along with the integer values of the rings on that tower. With OO, you'd have to either define a type for such list or do some casting of objects coming out of a generic collection, but neither is necessary in Scheme. The same would hold true with any dynamic language, of course.

Overall, it was a pretty fun exercise. It'd be neat if I could use functional programming at work. With the DLR, that just might be possible (I could at least write test code or internal utilities or something).

Wednesday, September 26, 2007

Complex isn't cool

I was IMing a coworker today talking about the ASP page/application life cycle. I made a common comment of mine, that the Internet is nothing but a terrible hack of a way to deliver applications. Then I commented, "web programming is so darn complicated" to which he responded, "yeah, ain't it great?"
While I think I can understand his basic point, this is something that was written about recently at worse than failure. While that post received lots of negative comments, there was no disagreement that developers often complicate things unnecessarily, which appeals to our engineering drive, and that often a better solution is the more mundane.
When I was in school I marveled at how complicated my code was. All that does this! Since it was my brain child (and only I could wrap my brain around it) there was a certain intellectual satisfaction involved.
As developers, we should all be on the lookout for this. The system gains nothing from it, and the next guy (whether ourself or some other monkey) stands to lose much (time, productivity, etc.).
It is sort of neat that a gazillion things come together to allow for killer apps on the Internet, but I would be very hip to a better solution (a standardized way to deliver smart clients or something). I'm not currently working on web apps, but when I do I always groan at the mountains of work that I'll have to put towards debugging the platform.
As I've already written (but can't be repeated often enough), simplicity (or reduction of complexity) is the most important goal in development.

Wednesday, July 18, 2007

Shades of Development

I just recently interviewed with a small company that needs someone to be the person who:
  • Maintains programs which patch together the pieces of their enterprise, e.g.; do some processing between the Internet order and the ERP system, write reports which draw on the ERP system, etc...
  • Identifies (or refines when others identify) and creates process improvement solutions.
  • Helps to create / refine content to the web site.
  • Does other sundry bric-a-brac.
Now this seems to be a good opportunity:
  • The people seem great.
  • The company is small and growing fast.
  • I would be able to call the shots.
  • I would be getting in at the ground floor.
  • Productivity is inversely proportional to team size (with the probable exception that 2 are better than 1).
It does, however, illustrate shades of development. One reason I'm code wannabe is that I often come across examples of the work of people who may be called "computer scientists". Or at least what they're doing is something orders of magnitude more compelling and or useful than what the average business developer does.

This position is not one for the computer scientist; nor should it be. The business has a specific gap that needs filling - they need someone to apply the correct amount of lubrication at all the correct points to keep the enterprise at optimum operational capacity. I frankly think I would be very good at this.

One thing they made clear: things move fast, there would be a great amount of context switching, and they want someone amenable to as many interruptions as the business generates. They don't want someone who is a "head down coder with the office door shut". Once again, this is perfectly reasonable, but it's not without drawbacks from the standpoint of a purist (in this case purist being a favorable term for one of those really smart guy programmers described above):
  • "Closed door programming" is to be preferred. But again, this presumes a certain type of programming. I wouldn't be creating the kinds of solutions that require intense, focused concentration (at least I don't think so).
  • Context switching is harmful. Steve McConnell's quote also comes to mind, "... programming requires more concentration than other activities. It's the reason programmers get upset about 'quick interruptions' - such interruptions are tantamount to asking a juggler to keep three balls in the air and hold your groceries at the same time." I don't think there's any doubt it is a productivity killer. In this company's environment, however, there's probably a greater benefit that outweighs it's drawbacks.
So this company's developer should be much different than many others. This introduces the range of development:
  • Corporate developers working on in house applications at BloatedCorp.
  • Rock stars creating startup Internet applications.
  • Lone developers working under unique conditions leading to killer solutions.
  • ISVs creating (formerly) shrinkwrap or (now usually) Internet apps.
  • Upper echelon programmers: those who create software for developers. Folks who work directly on .Net or Java internals or on IDEs.
  • Luminaries like Richard Stallman, Linus Torvalds, or Edsger Dijkstra.
  • Contract or independant developers: there's a whole sub range in here.
  • Gaming programmers.
  • Embedded systems programmers.
  • Academics who may contribute to practical projects.
  • Monkeys who act as typists for business analysts adding new widgets to code in a system that should be redesigned to be configured directly by business analysts. (That one is a bit specific because it's what I do now).
If I take the job, I will probably be busier than a one legged man (you know the rest), so I'll probably have to forebear studying the more C.S. intensive subjects as I am sometimes wont to do. One thing all good developers must share is the constant acquisition of new knowledge; just some more than others...

Tuesday, July 03, 2007

What's the single best rule to follow in programming?

Actually, I think there are 2 that are equally important; one that pertains to code construction, the other to design (and so it may be the single most important thing). I've recently seen these both expressed in a new light.

The frst (pertaining more to construction than the other) is brevity or code less. The first link, especially, sheds light on just how important this rule is.

The second, one which I'm going to rate as the best rule simply because it always pertains to architecture and as such should have a greater effect on the system under development, is reduce complexity.

The linked interview with software luminary Roger Sessions is the best I've heard in quite awhile. In the interview, Sessions proposes using "equivalence relations" to determine the best possible partitions in developing enterprise architecture.

You can listen to the interview for a further explanation, but I think his best points were about complexity. He demonstrates (by contrasting the huge reduction in potential states representable by a single program with 12 variables [and 6 states] to 2 programs with 6 variables each) that partitioning a system greatly reduces complexity.

Outwardly partitioned programs may not really be, however. If 2 "separate" programs (like services or whatever) share a database, they're not partitioned.

Sessions proclaims OO as the "worst partitioning technology". Now, I've read a fair amount lately in favor of FP over OO, and the arguments are pretty good. But I don't think they came close to Sessions' position against the traditional OO model - the creation of large hierarchies which merely tie everything together. He's not opposed to OO, mind you, just the typical implementation where reuse is a major goal.

"Reuse at the expense of complexity is unacceptable. Reducing complexity is much more important than reusing code; it is the most important thing."

The interview was so interesting to me that, for a moment, I felt excited about things like architecture. Then I remembered that I'm code wannabe and that I work at BloatedCorp (on the Behemoth project) and I snapped back to reality.

Friday, June 22, 2007

Who cares about code?

I'm the kind of code monkey who reads what I think are top blogs like coding horror, worse than failure, reddit (OK, it's not really a blog), and codebetter. I've read many of the programming classics like Refactoring, Pragmatic Programmer, and Mythical Man Month. As I find time, I'm going through SICP.
IOW, I strive for improvement in my "craft" (trite though that word may be).

But, other than at my first job, I haven't discovered anyone else who cares a lick about software good practice. Even if such "practices" are debatable, I used to expect that just about everybody endeavored to follow some. In interviews I've sat through, almost all the questions I've been asked have been nearly inane. I remember one interview a long time ago where one person focused on my ability to call windows API functions. Huh? I was so naive to think that they should ask me questions about my design practices or some other relevant topic.
One shop recently interviewed my and didn't ask anything about my practice, have me do any exercises, ask for a code sample; nothing. I was amazed.

I think the problem is that I glean info from the "upper echelons" of development while being employed at the bottom of the heap. I don't think I'm going to find many star coding shops posting for jobs on amazon or careerbuilder. It's not that I think I'm a star, but I'd at least like to work somewhere where such things are valued.

Another factor is that the code monkeys in these upper echelons aren't writing business logic for BloatedCorp. The shops where I've been employed during the last 4 years are building very narrow business specific systems, not crafting some innovative new system that businesses far and wide will use.

The work I'm doing now can hardly be called development. The architecture of the system is fixed, and there's no way it can (or even would be allowed to) be changed. I add new widgets (each doing pretty much the same thing); that's it. There's no ancillary technology (I just use my language's IDE); nothing at all other than scripting the rules for the new widget. It's not even a job a programmer should be doing - a business analyst should. If the system needs a change in the way it does something, I'm not the one to do it (for reasons outside my control).

IMO, this is a massive waste of my potential. But that's why I'm code wannabe. That's why I write these missives to you, diary...

Friday, May 11, 2007

Business Vs. Technical

This article at developer.* claims advice on the career path of a programmer. It suggests that the programmer needs to shift focus from technical to business specific knowledge.
Similarly, Bertrand Meyer from the esteemed ETH wrote in an IEEE Computer article, "make sure you know the business as well as the technology; that will set you apart from mere techies."

Both seem to guide the programmer away from engineering skills towards business skills. As a survival guide, my current experience seems to bear this out. The system I'm working on will be outsourced, but the business analysts will be retained. But I have a real problem with the former article especially. It's titled, "Career paths for Programmers," but IMO it should be titled "Why to give up Programming". This isn't career guidance for programmers who want to know how to make it as a programmer. This is advice for people who just want to make it, not caring how. Being a business analyst is nothing like being a programmer, generally speaking. I would never want to be a BA. Where I work, people with the BA title handle BA and QA, so it's kinda strange, but BA work in general couldn't possibly hold my attention; I would fail. There isn't anything related to problem solving or design in the BA's role. Further, I totally disagree with the quote in the article,

"he could train anyone in the technical skills he needed for a project, but finding those people with the necessary business skills to guide an IT project to success was something that could not easily be obtained".

I think the exact reverse is true. A person with good problem solving / design / logic skills either has such skills or not. They can be cultivated, but not acquired. Perhaps this person imagines a programmer / software engineer / developer as someone who just knows how to install and configure disparate technological tools. That would be a description of pure technical knowledge that anyone could learn, but programming isn't something you can just teach anyone.
Straight up business knowledge, on the other hand, could be stuffed into anyone's brain it seems to me. You can't train just anyone to be an actuary, but you can train anyone the details of your life insurance business and make them a BA.
I agree with the second article that the programmer who has the business knowledge is of more value, but this doesn't agree with the trend. I see what's happening to me as a trend; the software (technical) work is portioned out to those whose business is software. The particular business details are managed by BAs. So the software people know how to make good software. They don't devote themselves to business knowledge; they get that knowledge from BAs.
This seems natural to me. Now it may be that the software work may not have near the future that the strict business work will. But there's no way I'm going to morph into a BA. If I have to do something I hate, it surely won't be to fill my brain with details about Tonnage price of manila folders. I'd much rather be a sanitation engineer.

Thursday, May 10, 2007

Outsourced!

Par for the course for code wannabe. But it is a good thing. After a brief search, I'd resigned myself to my current position for personal reasons; now I must get a better job.

The decision of my employer to outsource the system I maintain seems a no-brainer to me. I could speak all day about the flaws (despite the fact that it does, in fact, work). The most logical reasons are these

1) The system needed a re-write (as much as many of the current developers would disagree). It makes more sense to do it over with fresh blood.
2) The third party company already handles analogous systems for competitors. It's inevitable that we would follow suit so our customers (who are actually middle men) can come to a central location when comparing.
3) Most importantly, my employer's core business isn't software and the industry has somewhat of a reputation for crappy (mostly internal) software. It makes sense to keep the focus on those employees who deal directly with the core business and outsource software to a company who has software as it's core business.

Point #3 begs the question that I've heard (read) asked many times. How much of a focus on business knowledge (of a particular vertical market) should a code monkey devote, and how much on software development itself? Subject for another post.

Thursday, April 05, 2007

Strangely Duplicated

I think avoidance of duplication is one of the most important maxims to follow in software development. Martin Fowler wrote in Refactoring, "By eliminating duplicates, you ensure that the code says everything once and only once which is the essence of good design". I could've sworn he also wrote, "all information in a system should be represented in one place", but I can't find that quote anywhere. Anyway, I would argue that it is more than just good design; it's essential if one wants to avoid problems.

Duplication was a problem I pointed out in some code recently. A design decision was made that is quite simply mind-boggling.
Here's the scenario: The application runs desktop/web which share business objects. A huge dummy object (discussion in itself) contains all input UI values. For desktop, the UI is refreshed based on the values in the UI object after validation on that object occurs. For web, a message pops up (someone else's decision) rather than the UI being refreshed.
So the decision was made that for the desktop, we merely reload the values (after validation may change them in the dummy object) into the UI. Simple enough. For the web, we add an additional giant object that contains the before and a copy of the after values. And for every single variable in the dummy UI object that is validated (>500) there is a separate method that:

  • Caches the original value

  • Sets the new value (if necessary)

  • Stores the new and old value along with a string indicating the name of the variable.


When asked why this was done, the initial reply was merely because the web "shows a user message rather than simply changing the variable on screen". When asked why it couldn't simply compare against the values in the UI object, the reply was essentially the same ("it needs to show a message"). In addition, the coder mentioned that the new data structure (with the duplicated data) could be a place to add additional functionality (can you say "YAGNI"?).

I pointed out (rather casually) these problems:

  • Duplication of data.

  • Forces the developer to remember to include a method copying the algorithm above for every new validation rule (which I already forgot to do once, prompting the discussion).

  • The above algorithm is duplicated ad infinitum.


The response was that this is merely my opinion, but I personally think it transcends opinion. If data is ever to be duplicated, there should be a very good reason for it because duplicated data opens the door for corrupt data - you may as well count on it.
In this case, not only is there no reason, one wonders how such a solution could even be contrived.

Anyway, this highlights 2 important red flags in the software development process:

  • Data duplication.

  • Multiple methods with near duplicate code.



IMO, if you see the former, your design needs correcting. If you see the later, figure out how to combine the code into a single method. If that's not possible, your design needs correcting.

Wednesday, February 07, 2007

Teamwork and Development

Code wannabe strikes again (just changed the name of this formerly work-group oriented blog so the tone of posts are different though still software oriented).

My boss tells me what I already know; I'm not playing well with my coworker. I've failed. Well, maybe not; lemme esplain:

  • My coworker (my senior) is in another state.

  • Our personalities don't mesh.

  • She has less experience (in time and most definitely in variety) than I do.

  • Our development philosophies are polar opposites; hers is git-r-done / hack it together, mine is do it according to widely accepted good development practices (although we both think our philosophy serves our customer best).

  • She wants to continue to follow the ancient existing architecture, I want to change it wherever possible.

  • And so it goes.


Because of the above, we don't communicate much. It's not terrible; but far from optimal. My boss suggested that he may move another developer (who is much more happy-go-lucky) to my spot and me to his system (a one man show).

So on the one hand, I've failed to be a team player - that's evident. But should I have been one? That's not evident. If I'm relegated to a one-man system should I simply embrace that as an opportunity to call all my own shots and flourish as perhaps I can best, or should I consider that a step down and always strive for collaborative development?

I believe one thing about lone development - it can be very fruitful. The Mythical Man-Month and copious other writings detail the difficulties with team development and I believe that applies right down to teams of as few as 3. 2 may be a unique situation what with XP and all (or even w/o XP as long as 2 developers are on the same page and communicate well). Yet, even with 2, the rule may apply. Could this cat have done what he did with a partner? A partner would surely have only slowed him down. Maybe that's only because he's a genius, but I suspect it applies to anyone who frequently gets in the zone during development.

Thursday, October 12, 2006

Brief guide to building a Delphi IDE AddIn

Someone in the Delphi IDE newsgroup asked the question, "Is there a guide anywhere about writing IDE addins"? After experiencing my own pain in building a small add-in (or is it plug-in?), I decided to make up a quick post. The answer to his question is a resounding "no." Well, you might consider this as something of a guide, but I had better luck getting started with these 2 docs:

The first thing to note is that I found that writing the add-in in .Net seemed to make it work for both Win32 and .Net Delphi projects.

When I started mine, I was really naive and thought there'd be some API with calls like GetStartNextMethod or something. You only get the buffer.

So here's the start - getting the source editor (sorry - snippets lost their formatting - too much work to put back in using blogger):

using Borland.Studio.ToolsAPI;

public class SourceViewer // base class
{
protected IOTASourceEditor fSourceEditor;
public IOTASourceEditor sourceEditor { get { return fSourceEditor; } }
public SourceViewer()
{
IOTAModuleServices moduleServices = BorlandIDE.ModuleServices;
if ( moduleServices == null )
{
fSourceEditor = null;
}
else
{
try
{
fSourceEditor = moduleServices.CurrentModule.CurrentEditor as IOTASourceEditor;
}
catch
{
fSourceEditor = null;
}
}
}
}


Then you use the source editor to get a reader to get the text of the buffer:

IOTAFileReader reader = fSourceEditor.CreateReader();

private string getRawSourceText( IOTAFileReader reader )
{
const int READ_CHUNK = 1600;

if (reader == null)
throw new Exception( "No file reader" );

StringBuilder sb = new StringBuilder();
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
Byte[] source = reader.Read( READ_CHUNK, 0 );
while ( source.Length > 0 )
{
sb.Append( enc.GetString(source) );
source = reader.Read( READ_CHUNK, 0 );
}

return sb.ToString();
}



To get the IDE to integrate your AddIn, implement IOTAMenuWizard:

public class TestPlugIn: IOTAMenuWizard
{

public static void Register()
{
IOTAWizardService WizService = (IOTAWizardService)BorlandIDE.GetService( typeof( IOTAWizardService ) );
wizardID = WizService.AddWizard( new TestPlugIn() );
}
....

Then implement the other methods of IOTAMenuWizard such as execute and enabled. I wanted mine to be enabled when any source file is open (referencing the first class above):

return new SourceViewer().sourceEditor != null;

Once your assembly is ready to go, register it with the IDE (so the IDE will load it on startup):
  • Create a key under HKEY_CURRENT_USER\Software\Borland\BDS\4.0\Known IDE Assemblies.
  • Give the key a name (don't recall if the name matters / where it might show up, but I think it has to have a name).
  • Add the path to your assembly there.

Friday, October 06, 2006

Ridding (not riding) the Range

I added a suggestion to David's list of potential improvements that we all discussed in Minneapolis. He asked me to describe why it's a problem and what I think the solution is...

Why the Range global is a problem
  • It's like a master key that tightly couples all parts of the system. We will not be able to separate annuity from life w/o either eliminating it or duplicating it for both.
  • It's a global (or rather a collection of globals; same thing). Reference my blog post for reasons why this is bad.
  • It prevents the furtherance of OO development in the system.
I Object!
Objects are objects for a reason. They should encapsulate their data. The range object is a circumvention of OO. A given product will manipulate any number of range variables for varying functionality. So rather than being able to look at the product class methods and members to determine it's behaviour, you may have to guess what range variables it manipulates to do so. Variables should be owned by the proper object that manipulates them. Range variables are manipulated by any other object in the system. This leads to conditional code multiplied all over. So instead of this:

BaseObject.DoThis;

We have this:

If Rng.Something then
SpecificObject.DoSomething
else if Rng.TheOtherThing then
OtherSpecificObject.DoSomething;

If the individual objects properly encapsulated their data, we wouldn't have this problem.

Solution
I don't see any other way than to:
  • Forbid adding any new variables to the range object (with exceptions for exigent circumstances).
  • Start removing it's variables. For each:
    • Search the system for it's use.
    • Determine which object at which level in the heirarchy should encapsulate the data.
    • Move the variable to the appropriate object.
    • Adjust the code that references it.
  • Whenever sets are encountered, this should be seen as an indicator that a new object may be needed. Sets (and their brother case statements) should be rare in OO (1). Unlike an object, they encapsulate nothing. So if you look at a set in code, you learn nothing. In order to learn how the system manipulates the members of the set, you would have to search the system for all references to the set. When you do this search, you will no doubt encounter many case statements and for loops. If the business logic were instead object based, you would simply call BaseType.DoSomething and polymorphism would handle the conditional behaviour of the members of the set. Thus you don't end up with case statements and for loops that usually start out at a manageble size, but enevitably grow into something that is very difficult to maintain.
No doubt this will initially lead to some other objects becoming bloated, but this is a process. The bloated objects should, in turn, be distilled into more granular objects.

1) Refactoring, p. 34, 82

Tuesday, October 03, 2006

Good Javascript Reference

I was working on something for our new App Wizard Search today and came across this Javascript reference on the Mozilla developers' site.

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference

If you go up a level or two there are all kinds of sections about various web development topics as well. It is all geared for Mozilla but with some consideration it would most likely be applicable across most browsers.

Friday, September 29, 2006

Regular Expression Tools

Since Kelly has been developing some regular expressions for modifying VB6 code in preparation for migration to VB.net (because he needs some things to end up differently in VB.net than the built in upgrade wizard would cause them to be), I had regex on the mind and decided to listen to this podcast about them.

If you've never used them before, regular expressions are basically just strings with special characters and placeholders for manipulating (not just finding) text. This is one I've used a few times to search through code. I need regex because I want to find all ocurrences where any index of SameArray is modified but the identifier within the brackets varies.

SomeArray\[\w+\]\s+:=
  • The text between the array index brackets can be anything. 'w' indicates anything that can be part of a language identifier.
  • The brackets themselves are escaped because they normally delimit character sets.
  • The '\s' indicates a space. There might be more than one space between the right bracket and the assignment.
  • The '+' indicates one or more of the preceeding token.

This is a simple expression that makes for a much better search. I didn't have it until now, but Regulazy is a graphical tool that is perfect for creating such expressions quickly. Regulazy creates .Net regular expressions, and something new I learned on the podcast is that there is no "standard" implementation for regex. The tool I use to search through files with the above expression is a simple utility done in Java, and this expression works for Java too. The basic tokens are the same (kind of a standard, I guess), but each implementation varies; for example, .Net allows you to name groups and refer to them in other areas of your expression. Perl allows you to use variables in the expression.

The podcast gave great resources for creating the expressions, but not for using them. I haven't come across many good utilities for searching files with regex expressions (although it wouldn't be much work to write one with the .Net System.Text.RegularExpressions namespace). Neither Notepad++ nor the grep search tool that comes with the GExperts suite that we use would run my expression (even though it uses only simple tokens that should be the same across all implementations).

Here's the thing about regex; they can be very powerful. A single expression can be used as a substitute for a class with tons of conditional code. But then, expressions like this are not very maintainable since they end up looking like a cartoon character's long outburst of profanity - that's the trade off. One thing that helps a bit is that you can insert comments in .Net expressions like yay: (?# Look Mom! There's comments in my expression! ).

Despite the complexity, some validation requirements are a no-brainer match (no pun intended) for regex - like validating email addresses. I wrote an email address validation routine/object once - not easy after reading through the actual RFC for email addresses. The .Net expression for this and other very common validations are available on MSDN. There are many more available on regexlib.com (along with an online expression tester). I'm sure the expression that Kelly developed, no simple expression that, would be a good addition to regexlib.com.

Even the regex guru guest of the podcast recommended that they should be used sparingly. If you do want to create one, use his regulazy tool. That will get simple ones created for you very easily. Then, if you need to create a sophisticated expression (replacements, named groups, ect.), use his Regulator tool. This app includes things like intellisense for expression creation. It will also interface with regexlib.com to help you find a pre-existing expression that may suit your needs. Both are free!

Another very useful resource that isn't regex, but is related is logparser.com. This site maintains utilities that allow SQL like querying of commonly used log files (like IIS or SQLServer).

One more note for .Net regex; if you are using the regex object to match repeatedly over alot of text, you can pass a param to the regex class that will cause the runtime to create an assembly (a class hard coded to meet your expression's specs) and run that assembly for speed. Cool, huh?

Wednesday, July 12, 2006

Small Methodology

Judging from the amount of posts recently, I think I'm writing this to myself. Oh well; dear diary...

In this post I'm extolling the virtues of smaller methods.

When I say small, how small do I really mean? Several times1, I've read no larger than what fits on a single screen although that's certainly debatable.
Code Complete2, the best code construction book ever, has a section titled "How Long Can a Routine Be?" It is surprisingly liberal, basically recommending smaller methods yet presenting some evidence that larger methods are not necessarily bad. It almost contradicts itself in another section, "Scope", wherein it recommends "breaking related statements into separate, smaller routines". The latter advice is given in the context of variable scope, so I suppose the lesson there is that length isn't as much a concern if there are few local variables involved. But... I don't ever recall reading anything advising larger methods. The archives of this site contain no end of examples of huge (edited) routines that caused no end of problems.

In any case, here are some pros for smaller methods:
  • Much easier during maintenance to find the area of code needing change (let's see I know I need to change something somewhere in PlayThatFunkyMusic, but it's 1000 lines long... where?). Note that you are in maintenance mode even when first developing the code.3
  • Code is so much more readable. Instead of trying to figure out if the next 10 lines are relevant to my problem, I read a MethodNameThatTellsMeWhatItDoes.
  • You end up with more efficient code since it's easier to see what you're doing. If you keep adding more and more to a method w/o breaking it out to additional methods, there's a good chance you'll do more than what's necessary. An example that surely came about in such fashion that I came across was a 600+ line method that had a nested 150 line if statement. The nested if checked the same thing as the outer if, but had an else. The compiler probably didn't give the unreachable code error because it was confused - or else I was confused. Either way it made for a very difficult debugging exercise.
  • Communication of intent. Smaller methods with descriptive names are prefferable even to comments. Intent is best communicated in structure and naming. From Martin Fowler, "A block of code with a comment that tells you what it is doing can be replaced by a method whose name is based on the comment. Even a single line is worth extracting if it needs explanation".4

And here are some cons:
  • Function call overhead. Not! Only in a case of a method/methods being called zillions of times would function call overhead (the cost of setting a spot in the register, adding to the stack, transferring execution to the new method, etc...) make a difference. Besides, we never know when the compiler inlines methods under the covers eliminating this perf cost altogether.
  • Developer has to navigate around among more methods to get to where he/she needs to be. There is some validity to this argument, but I think surely outweighed by the benefits and by the fact that there are ways (bookmarks, rapid finding [are you using GExperts?] and navigating among methods) to compensate for this.
In Extreme Programming Adventures in C#5, Ron Jeffries (basically the founder of the XP movement) advises, "The 'right' structure for a method that does more than one thing is called 'Composed Method.' Always create a method that is composed of nothing but method calls, all at the same level, rather than expanding any of the ideas out in line." His example refactors this:

public InputCommand(StringReader reader)
{
lines = new ArrayList();
String line = reader.ReadLine();
while (line != null && line != "*end")
{
lines.Add(line.TrimEnd());
line = reader.ReadLine();
}
CleanTheLines();
}

into this:

public InputCommand(StringReader reader)
{
ReadLines(reader);
CleanTheLines();
}

So each method that does multiple things makes calls to other methods. Once a method does one distinct thing, it no longer needs refinement. It's certainly my experience that such code is very easy to follow.

Oh, and remember - BDS (and Visual Studio 2005) make extracting methods pretty easy. Code on, brothers and sisters. Oh wait, I'm just writing this to myself...

Notes
1) Most recently in "Rules for Developing Safety Critical Code", IEEE Computer, June 2006; Code Complete also mentions this rule of thumb.
2) Code Complete is Avail on the Intranet even though a search for it shows no results.
3) Interview with Andy Hunt and Dave Thomas, "All Programming is Maintenance Programming".
4) Refactoring, Page 77.
5) Extreme Programming Adventures in C# is Avail on the Intranet. Reference Chapter 9 under section, "InputCommand Refactoring".

Friday, May 12, 2006

Intro to WinFX

Jenny and I attended a MS event about WinFX on the 12th. Hopefully, this post will serve as a mini intro for anyone else interested in Microsoft's upcoming technologies.

WinFX is basically MS's new API for windows. It can be accessed via .Net 2.0 code and will come bundled as part of the next OS, Vista, as well as being available to install on WinXP and Server 2003.

There are 3 pillars of WinFX that all follow the somewhat famous architecture outlined by Jack Greenfield in his article, "Software Factories." Greenfield was formerly a bigwig at Rational, where everything had UML as it's foundation and was supposed to be the shiznit, but fizzled. Now his new ideas of using useful models to build real software (though there's more to the article) are becoming a reality. So the model is the code - just as you can design a form in our current tools and it is the actual form you run, so you can create models in a designer and it is the actual logic.

Another main point about the new paradigm of development is that imperative and declaritive code can be separated much more easily. So all the details of what you want to do (connect to this data store, use this protocol, make the interface look like this) are very easily separated from how (business logic). All the declarative code goes into markup (XML or XaML).

So the 3 pillars are:
  • Windows Presentation Foundation - The all new UI.
  • Windows Communication Foundation - Web Services (or services that may reside on the same machine) enabling a service oriented architecture at any level.
  • Windows Workflow Foundation - Modeling as described above.
Presentation Foundation (formerly Avalon)
The UI uses "XaML" to represent any damn thing you can imagine. The graphics engine supports regular bitmaps and vector graphics. There is a pure UI designer piece called "Expression" whose graphics manipulation capabilities I can't adequately describe. With XaML you can describe how you'd like a graphic to rotate, zoom (and vector graphics are crystal clear at any zoom factor), or whatever. The controls you create that display all these graphics can reference templates for consistency. Then the XaML is transferred to the developer. Here's a video of a real application utilizing the presentation foundation. One presenter mentioned that you will be able to run the same XaML on the desktop as is the browser, but this didn't seem to add up as there was a different Expression tool for web pages...

Communication Foundation (Formerly Indigo)
Connect to anything using any transport mechanism with the same type of interface. In a sample app, the presenter had connected to web services, but had also wrapped up communication with a regular human interfaced web page (querying availability of a product on a retailer's web site) for use in the same fashion. So you communicate with another WinFX local service the same way as a web service.

Workflow Foundation (Formerly I don't know what)
There used to be another piece to the WinFX pie called "WinFS," the "FS" for file system, I presume. This piece dealt with an entirely new way to manage files. Files had extensions (not in the name) that allowed for sophisticated organization and retrieval. I'm not sure how much of that stayed in WinFX; as far as I can tell workflow foundation only deals with what I discussed above about being able to visually design your application's logic.
You drop activities down on a design canvas and wire them together as a sequential diagram, a state machine (basically event driven), or as a rules driven machine. You can even simply set a breakpoint on your activities and then step into them if they have additional code behind them. I think this will really encourage code re-use and third party vendors are already making lots of useful "activities". So one of the out-of-box ones (I think) would be send an email message. Drop down that activity, set some of it's properties and let 'er rip. Activities can contain other activities, so you could even have a main activity be one that is the main gateway to persistence (save to data store). Then each time execution enters that activity, it may flow into different sub-activities. Another cool activity example is Amazon's purchase item activity.

Tuesday, May 09, 2006

Refactoring to eliminate duplication

As with a previous post, this may be obvious, but I think merits elucidation and discussion.
There are many cases where some code cries out, "refactor me!", but there never seems to be sufficient time. In the opinion of most leaders in the software community, however, we should make time; our efforts will always pay off.

So here's something commonly seen:

case PartyAnimal.Age of
 2..12:
 begin
  PutRightLegIn;
  PutRightLegOut;
  DoHokeyPokey;
  ShakeAbout;
 end;
 13..19:
 begin
  PutRightLegIn;
  PutRightLegOut;
  DoMacarena;
  ShakeAbout;
 end;
 20..25: //etcetera

We have some obvious repetition here that should be extracted into a method (wouldn't it be really cool if we had an IDE that would do this for us? It does, you say? Please teach me how; BDS gives me an error every time; VS2005 never did).

To emphasize why it should be extracted into a method:
  • When (note - not if) PutRightLegIn needs to change in every case, the change can be made in one place.
  • It makes for less code in the listing (and in the .exe). Less code to do the same thing is always a good thing. (1)
  • To quote Martin Fowler, "the essence of good design is ensuring that the code says everything once and only once." And better design makes for more efficient maintenance. (2)
  • It follows the DRY principle: Every piece of knowledge in the development of something should have a single representation. (3) The piece of knowledge in this case is RightLegIn, RightLegOut, X, ShakeAbout.

So, of course, our refactored case statement (after adding our new method, DoPartyDanceWith) looks like:

case PartyAnimal.Age of
 2..12:  DoPartyDanceWith( HokeyPokey );
 13..19: DoPartyDanceWith( Macarena );
 20..25: //etcetera


I'm hoping the next time each of us has to modify something that looks like this, there will be a greater itch to refactor, then modify.

Notes:
1) The Art of Unix Programming (and a zillion other places)
2) Refactoring
3) The Pragmatic Programmer (and many other places)

Wednesday, May 03, 2006

get_ and set_

By default, if you have a property named MyProp, Delphi assumes methods named GetMyProp and SetMyProp. Per a Delphi 2005 book I have read, Delphi.NET actually compiles this code creating new methods get_MyProp and set_MyProp which in turn call the original methods. We could eliminate this extra layer if we just use get_ and set_ for the original names. This would have at least a minor improvement in performance. So, should we set a standard of get_ and set_ for future property specifier names?

PS: if the specifiers simply refer to an element such as FMyProp, Delphi still creates get_ and set_methods that then access FMyProp.

Read only class attribute

Say I have a class that has some attribute that is basically read only. Each child of the class has a fixed value for this attribute for all instances of that child class. Three possible ways to implement this are:

1. Add an element named MyAttribute. In the constructor, set the value of MyAttribute.

2. Add a function named MyAttribute that is overwritten in each child class.

3. Add an element named FMyAttribute and then add a MyField property with a read specifier of FMyField. In the constructor, set the value of FMyAttribute.

4. Add a Get method named GetMyAttribute and then add a MyField property with a read specifier of GetMyField. In each class, override GetMyAttribute.

I assume option 1 is the least desirable since it doesn't enforce read-only and basically does not fit in with the standards we are striving for. Option 4 is seems to be the most robust, but is overkill. Any opinions.

Tuesday, May 02, 2006

GAIM: Lotus SameTime client replacement

When ING blocked the external IM ports I for one found the Lotus client lacking in features compared to the clients that we had been using. Well the other day on my Mac I noticed that the client I was using had an option for SameTime. This made me ask why we couldn't use a different client at work as well. So I did some looking and found several clients that said they had SameTime support. The client I had previously been using, Trillian, did mention SameTime support but only in their "Pro" version. Another client that said they support SameTime was GAIM. I have been using this client on my Linux box at home for a few years now and have been happy with it. It is free, open source software. There is a Windows port of this program and the rest of this post details my experience so far with it.

If you want to try GAIM for SameTime you first need to download the client using the link at the top of this page. Once downloaded go ahead and install the program. I used the default install options.

Next you will need the GAIM plugin for the SameTime protocol. This plugin is Meanwhile. It can be downloaded from this page. (Updated) Be sure to pick the Windows version. It should be the file with "win" in the name. Once downloaded you can run the install. It should place the plugin into the appropriate folder.

Next open GAIM. It will present you with a login dialog and most likely open the Accounts window. I believe you need to go into Tools->Preferences and select the Meanwhile plugin in the plugins section before adding an account. Forgive me but I don't remember the exact steps for this but I believe it was intuitive.

Once the plugin is active you should be able to use the accounts dialog to add a new account. Select Meanwhile in the type dropdown list. Enter your username and password. Your password should be the same one used for logging into Exchange. For the servername I cut and pasted out of the Lotus client settings. Here's a screenshot of my account settings.

You should now be ready to connect and start IM'ing. For me my buddy list appeared the second I successfully connected. Since it is stored on the server you can make changes here or in the Lotus client and both see the changes. The only area that I've had trouble figuring out in GAIM is adding new buddies. To do this I switch to the Lotus client, add the buddy, then go back to using GAIM.

From here you can go in and customize your settings in Tools->Preferences. I've turned on several of the plugins to improve the behavior as well as logging, conversation history, etc. Here's a screenshot of my pimped out IM client.


I've been using this client for a couple days now with no noticable problems. If all else fails we have the Lotus client to fall back on. Happy IM'ing!