July 27, 2004
Grand Unification Theory
We recently switched to VS.NET 2003 (.NET 1.1) at work, yet we're still using third party assemblies compiled under .NET 1.0. Now, ideally, you'd want assemblies recompiled to be sure that they are running as .NET 1.1. We happen to have a source license to these controls, so that option is available to us. But what about assemblies that you can't recompile? What happens when you reference them from an application compiled under .NET 1.1? I hadn't ever considered this scenario. To me, the only thing that makes sense is that these referenced assemblies are forced to run under the same runtime as the main application, even though they were compiled under 1.0. And as it turns out, that is exactly what happens:
The .NET framework assemblies have both of these problems. During development of the v1.0 product, the CLR / FX test teams explicitly tested the v1.0 FX stack against the v1.0 CLR. The same testing occurred for the v1.1 CLR and the v1.1 FX stack. Side-by-side testing naturally results in an explosive matrix of test cases, and because of this, there was no explicit testing done for mixing and matching v1.0 and v1.1 frameworks assemblies. Furthermore, there are some FX assemblies (I believe winforms is one such example) that are not designed to be run-time side-by-side capable.A generalized solution for addressing the problems above is still not yet available. In the interim, a CLR v1.1 feature known as unification policy was developed that addresses these problems (albeit in a very limited way). Unification is a form of binding policy which occurs after application policy is evaluated, but before publisher policy is applied. A hard-coded table of assemblies which shipped in the v1.1 CLR product is consulted and references to any version of assemblies in that list are automatically redirected to the version of the assembly that shipped in the v1.1 product.
Through unification policy, it is possible for a v1.0 application to be configured to run against the v1.1 CLR (via the
or configuration tags), and automatically have the references to the v1.0 FX stack redirected to the appropriate versions for the v1.1 CLR, with no re-compilation, or manual authoring of binding redirects by the developer or end-user. Similarly, an app built against the v1.1 CLR can utilize shared components written for the v1.0 CLR, and again the v1.0 FX references will automatically be redirect to the v1.1 stack. Through unification policy, the v1.1 process will always use v1.1 FX assemblies, and there will not be any mix/match conditions which could cause problems at run-time.
As a semi-related aside, it's disgraceful the way the 1.0 runtime is treated like a third class citizen at Microsoft. For example, we ran into a massive bug in the (hotfixed!) 1.0 version of System.Data.OracleClient. This bug has another hotfix, but only for 1.1. Now, 1.0 is about two years old, which doesn't seem that old to me. But just try getting a hotfix for a 1.1 bug back-ported into the 1.0 runtime. In the words of the Smash TV announcer: good luck-- you're gonna need it!
July 26, 2004
Just Say No to Finalization!
I am working with some classes that wrap unmanaged APIs, so I have to be concerned with releasing the resources associated with these APIs-- eg, the IDisposable interface. I was a little confused about the distinction between Dispose() and Finalize(), and in my research I found this article by Brent Rector of Wintellect:
In a worst-case scenario, your object's Finalize method won't run until your process terminates gracefully. (Actually, the real worst case is that it never runs at all because the process terminates abnormally.) Shortly thereafter, non-memory resources will be released anyway, so the Finalize method served no real purpose other than to keep the application from running as fast as it otherwise could.It's a good point. In a true worst case scenario-- unhandled exception time-- you won't get any benefit from Finalize. So, given the (evidently) large performance penalty of Finalize, why bother? I tend to agree. However, the best practice according to Microsoft is, if you implement IDispose, you should also implement a Finalizer:Just say No to Finalize methods!
Private _IsDisposed as Boolean = False
''' <summary>
''' public Dispose method intended for client use
''' </summary>
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(False)
GC.SuppressFinalize(Me)
End Sub
''' <summary>
''' common Dispose method; can be called by client or the runtime
''' </summary>
Protected Overridable Overloads Sub Dispose(ByVal IsFinalizer As Boolean)
If Not _IsDisposed Then
If IsFinalizer Then
'-- dispose unmanaged resources
End If
'-- disposed managed resources
End If
_IsDisposed = True
End Sub
''' <summary>
''' called by the runtime only, at garbage collection time
''' this protects us if the client "forgets" to call myObject.Dispose()
''' </summary>
Protected Overrides Sub Finalize()
Dispose(True)
End Sub
It's all rather contradictory.
July 23, 2004
DEVELOPERS^3
There's an interesting article documenting the dramatic uptake of .NET
Want more proof .Net is taking off? Consider the following: In May, Forrester Research released a report that found 56 percent of developers polled consider .Net their primary development environment for 2004, compared with 44 percent for J2EE. In certain verticals, the percentage gap grows even wider; for example, 65 percent of developers working on public-sector projects said .Net was their primary platform vs. 35 percent for J2EE, while 64 percent of business-services developers led with .Net over 36 percent who led with J2EE. In VARBusiness' own State of Application Development survey, also completed in May, 53 percent of solution providers polled reported developing a .Net application in the past year, and 66 percent said they planned to build one in the next 12 months.This really isn't surprising to me, for a couple reasons."Frankly, we were surprised to see [.Net] as dominant as it was," says Nick Wilcox, a research analyst at Forrester.
Credit a down economy for something, if you will, but the fact is that much of the .Net adoption is fueled by a thirst for business efficiency. A grassroots legion of developers see .Net as their ticket to creating software they can get to market quickly and cheaply, a must in this continued era of short-term projects and calls for instant ROI. In VARBusiness' State of Application Development survey, the No. 1 and No. 2 reasons respondents said they chose .Net as their primary development platform were ease of use and quicker time to market, respectively.
- .NET has an incredible pedigree, particularly for those of us who were exposed to Borland's Delphi in 1995. Delphi was the darling of windows developers everywhere, and .NET is basically Delphi Reloaded (that's what you get when you hire Anders Hejlsberg away from Borland). It's even better!
- The Visual Studio .NET IDE is the gold standard in developer productivity. I'm not aware of any other IDE that even comes close. Yes, the most usable product is the one people end up using. Go figure.
- Where Microsoft goes, so go the Visual Basic developers-- the largest group of developers in the world.
Just ask Steve Ballmer: DEVELOPERS, DEVELOPERS, DEVELOPERS. Own that mindshare, and you own the world. The great thing about .NET is that, whatever your opinion of company, Microsoft is gaining mindshare the old fashioned way: by producing a quality product. Gotta love that.
July 22, 2004
Rethrowing Exceptions
There's a bit more subtlety to rethrowing exceptions than most developers realize. Although this topic is covered very nicely at The .NET Guy blog, here's another example:
Try
session = smgr.getSession(_strDocbaseName)
Catch ex As Exception
If ex.Message.IndexOf("authentication failed") > 0 Then
Throw New Exception("more info about the exception", ex)
Else
Throw
End If
End Try
The important thing here is to preserve the call stack, and that means
- when throwing your more-informative exception, include the original exception as the InnerException (second parameter) for reference
- when you decide you can't handle the exception, re-throw the original exception as is.
Throw ex
... would do the same thing, but less code is almost always better, IMO.
So then the next natural question that most developers ask is, "When should I catch exceptions"? And it's a very good question. Here are some guidelines that I have found useful.
- Unless you have a very good reason to catch an exception, DON'T. Exceptions are supposed to be exceptional, just like the dictionary meaning: uncommon, unusual. When in doubt, let the calling routine, or the global exception handler, deal with it. This is the golden rule. The hardest kinds of exceptions to troubleshoot are the ones that don't even exist, because a developer upstream of you decided to consume it.
- If you can correct the problem implied by the exception. For example, if you try to write to a file and it is read-only, try removing the read-only flag from the file. In this case you handled the exception and fixed the problem, so you should eat the exception. It doesn't exist, because you fixed it.
- If you can provide additional information about the exception. For example, if you fail to connect via HTTP to a remote website, you can provide details about why the connection failed: was the DNS invalid? Did it time out? Was the connection closed? Did the site return 401 unauthorized, which implies that credentials are needed? In this case you want to catch the exception, and re-throw it as an inner exception with more information. This is a very good reason to catch an exception, but note that we are still re-throwing it!
- Always try to catch specific exceptions. Avoid catching
System.Exceptionwhenever possible; try to catch just the specific errors that are specific to that block of code. CatchSystem.IO.FileNotFoundinstead.
July 19, 2004
Go, Monkey!
There's an interesting interview with Miguel de Icaza at news.com. Miguel is the primary developer behind the open-source port of the .NET runtime known as the Mono Project. This project was recently purchased by Novell, ostensibly to bolster the development tools available on Linux. Miguel seems refreshingly free of the dogma I expect from Linux and open source developers in general:
Oh, Unix is a world of pain for developers. Now, basically what we got is very modern IDEs (integrated development environments) for developing software on other platforms.Also some interesting insights on the J2EE vs. .NET discussion:So, for example at Novell--and this was a choice that I really wasn't involved in--but they looked at the (Mono) technology and they found exactly what they were looking for implementing this thing called iFolder 3.0, which is a new version from scratch with many new features, similar to the Longhorn WinFS with synchronization of data, backups, all kinds of interesting things. They could write in C++, but the schedule would just go out the window, or they could do it in C#, but it would be Windows. And when Novell acquired Ximian they had the option of building the same software that runs on Windows and on Linux.
So today they support Windows, Linux and the Mac OS with the same tool base. It helps developers focus more on what they are doing instead of with the nitty-gritty details of the specific platform. There's a lot of new development happening on Mono. We (at Novell) are centralizing on Mono as our internal development platform.
Today what's happening is that ASP.Net (Microsoft's system for building Web applications) is replacing, it's basically pushing J2EE (Java 2 Enterprise Edition) aside. We did a study at Ximian when we were trying to find customers for Mono. We found that people said that it was 25 percent more efficient to build in ASP.Net, because they have to do all this academic crap (with J2EE). Microsoft later funded a similar study and they came up with 30 percent. We interviewed about 25 customers about why would you buy Mono, why not J2EE, and we came up with that.It also seems that mono has focused on the server side of things with ASP.NET and basically punted on the whole GUI/winforms side of .NET, and I can't blame them.The problem with J2EE really is that it became very, very academic and the complexity of all these perfectly designed systems in schools does not necessarily map when you have deadlines and all kinds of other things. Twenty-five percent means we can develop it in a shorter time period. We can actually hire less people to do this thing. So those shops that spend $200,000 to $2 million say it's a one-year project. We are talking about relatively small shops--four or five developers or six developers to maybe 20 developers. If you can save 25 percent, it's a very big savings there. So, it's just because the technology is not as pretty as it could be or as nice as it could be, but it gets the job done. So, it's not Java's fault; it's more the framework has not been designed for these users.
Q: Will you be able to port everything that Microsoft does on Windows to other operating systems?Still, it's great to have options. Who doesn't like the idea of having flexibility in platform deployment choice, at least in theory? It certainly helps .NET's credibility a lot in comparison with "write once, debug everywhere" Java.The new UI stuff, I have struggled a lot with what we are going to do with our toolkit.
That's why I say, go, Monkey!
July 14, 2004
VB vs. C# -- FIGHT!
If I see one more blog entry complaining about VB's verbosity, or the elitism of C# developers, I think I'm gonna puke. Why can't we all just get along? Part of what makes the .NET Runtime unique is that it offers you a choice of syntax; we should embrace that philosophy, rather than wasting a lot of time sniping at perceived slights. If I wanted a single language to bind them all, I'd be writing in Java. 'nuff said.
One of the first e-books I read after .NET was released was Daniel Appleman's Visual Basic.NET or C# - Which to Choose. And it's still the best one on the topic. The answer, of course, is: it depends. The real choice you make is to use the framework; getting obsessive about the bits of duct tape we use to run the framework through its paces is completely and utterly missing the point. Which brings me to my favorite passage from the e-book:
So let me make one thing perfectly clear. Any of you who feel that the syntax:
if() { }is somehow morally superior to:
If .. Then End Ifare fools.
And yet, one of the things Dan predicted has come true: C# developers are paid more.
If the perception survives that C# is somehow better than VB.NET, there will be a set of managers and clients stupid enough to pay more for C# programmers than VB.NET programmers with identical experience.Written in early 2002, and still eerily accurate to this day.Now, as an ethical programmer, I know that you will question the wisdom of these managers and clients and point out to them the fact that there is no rational basis for paying more for C# developers than VB.NET. Why, you might even show them a copy of this very article to prove the point. But we both know that some will not be persuaded. Language choice is as much an emotional as a logical decision. It seems clear to me that in a case where a manager or client insists on paying more for C# development, you have a moral obligation to take their money, knowing in doing so you help promote the capitalist system that insures survival of the most efficient organizations. Just don't accept your pay in the form of stock or options, because the organization you're working for probably has other efficiency problems as well.
Anyway, since the need to convert between VB and C# comes up on a near-daily basis, here are some resources I've found helpful.
- Lutz Roeder's amazing Reflector, which can decompile .NET code to the language of your choice. If there's ever a nobel prize for .NET coding, Lutz is the obvious frontrunner.
- Quick reference guide to highlight some key syntactical differences between VB.NETand C#. Because sometimes I forget what { and } mean.
- Online C# and VB.Net translator. Great for quick conversion of snippets with minimal thinking. I've used a few and I like this one.
July 13, 2004
VS.NET 2003 VB outlining broken
Evidently the VB code outlining support is completely broken in VS.NET 2003. Why hasn't this gotten more publicity?
We used the code outlining features all the time at work in 2002, and they worked great. But after switching to VS.NET 2003 we noticed that selecting Edit, Outlining, Toggle All Outlining does nothing in VS.NET 2003 for VB code. Not only that, but turning off Tools, Options, Text Editor, Basic, VB Specific, "Enter outlining mode when files off" doesn't work either. Doh! I can't believe this hasn't been fixed yet in a patch for VS.NET 2003, because it makes working with #Region -- which we use a lot -- pretty much impossible.
I searched around for a bit and found this blog entry by Roland Weigelt. While it's not a fix, per se, it does add support for #Region outlining at the very least. I was not able to get the code he posted to work, rather, I used the code posted in the comments by Andrew Eno:
Imports EnvDTE
Imports System.Diagnostics
' Macros for improving keyboard support for "#region ... #endregion"
Public Module RegionTools
' Expands all regions in the current document
Sub ExpandAllRegions()
Dim objSelection As TextSelection ' Our selection object
DTE.SuppressUI = True ' Disable UI while we do this
objSelection = DTE.ActiveDocument.Selection() ' Hook up to the ActiveDocument's selection
objSelection.StartOfDocument() ' Shoot to the start of the document
' Loop through the document finding all instances of #region. This action has the side benefit
' of actually zooming us to the text in question when it is found and ALSO expanding it since it
' is an outline.
Do While objSelection.FindText("#region", vsFindOptions.vsFindOptionsMatchInHiddenText)
' This next command would be what we would normally do *IF* the find operation didn't do it for us.
'DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")
Loop
objSelection.StartOfDocument() ' Shoot us back to the start of the document
DTE.SuppressUI = False ' Reenable the UI
objSelection = Nothing ' Release our object
End Sub
' Collapses all regions in the current document
Sub CollapseAllRegions()
Dim objSelection As TextSelection ' Our selection object
ExpandAllRegions() ' Force the expansion of all regions
DTE.SuppressUI = True ' Disable UI while we do this
objSelection = DTE.ActiveDocument.Selection() ' Hook up to the ActiveDocument's selection
objSelection.EndOfDocument() ' Shoot to the end of the document
' Find the first occurence of #region from the end of the document to the start of the document. Note:
' Note: Once a #region is "collapsed" .FindText only sees it's "textual descriptor" unless
' vsFindOptions.vsFindOptionsMatchInHiddenText is specified. So when a #region "My Class" is collapsed,
' .FindText would subsequently see the text 'My Class' instead of '#region "My Class"' for the subsequent
' passes and skip any regions already collapsed.
Do While (objSelection.FindText("#region", vsFindOptions.vsFindOptionsBackwards))
DTE.ExecuteCommand("Edit.ToggleOutliningExpansion") ' Collapse this #region
objSelection.EndOfDocument() ' Shoot back to the end of the document for
' another pass.
Loop
objSelection.StartOfDocument() ' All done, head back to the start of the doc
DTE.SuppressUI = False ' Reenable the UI
objSelection = Nothing ' Release our object
End Sub
End Module
To install, use the steps Roland outlined:
- Open the Macros IDE (Tools - Macros - Macros IDE)
- Create a new module "RegionTools", replace the code in the created file with the posted source code, save file.
- Assign keys in VS.Net (Tools - Options - Environment - Keyboard).
Thanks Roland and Andrew for your tips!
July 11, 2004
Virtual PC 2004
This won't be news to a lot of you, but I was playing around with Microsoft Virtual PC 2004 today:
And it's very cool. I know, I know, I'm probably the last developer on the planet to get wise to the benefits of virtual machine technology. In my defense, I have a lot of computer hardware in the house, so if I needed an environment to test something in, I'd typically just grab one of my extra PCs and have my way with it. The additional layer of software translation-- emulating an x86 PC on an x86 PC-- seemed unnecessary to me, like the VGA port on a flat panel monitor. Lately I've been reconsidering the convenience factor of the software alternative.. particularly given the excessive power of today's desktops.
If you are wondering just how this software can make your life easier, allow me to quote from the product FAQ:
• Safety net for OS migration: Virtual PC provides IT Professionals with a cost-effective safety net for certain employees to run critical legacy applications on an interim basis while IT Pros continue their current migration plan to a new OS. Microsoft operating systems and applications running on VPC virtual machines are fully supported in compliance to the MS product lifecycle guidelines. So Windows XP Pro deployments can continue on schedule, even if faced with unanticipated application compatibility issues, allowing Microsoft customers to take advantage of the ROI and productivity gains of more current operating systems.• Rapid reconfiguration: Virtual PC increases the productivity and responsiveness of technical support and help desk employees by enabling them to rapidly switch to alternate operating systems or configurations, eliminating lengthy reconfiguration and rebooting between calls. Virtual PC can also be used by training professionals to rapidly reconfigure custom environments for use in training, and to eliminate lengthy reconfiguration downtime between classes. Use of Virtual PC in these scenarios results in increased customer responsiveness and lower operating costs.
• Accelerated software testing and debugging: Virtual PC enables developers to test and debug their software on a number of different platforms in a timely and cost effective manner, all on one PC, improving software quality and reducing time to market.
It's like having an entire test lab full of machines, loaded with every kind of crazy OS and configuration you can imagine. Plus, on each machine you get rollback and "clean image state" by saving hard drive image checkpoints-- so you don't have to reinstall anything. No need to even burn CDs or DVDs; you can mount ISO images in the virtual CD drive. Definitely convenient!
If you're worried about performance, as I was, don't be. A good rule of thumb is that same-system emulation costs about ten percent of raw performance, which is reasonable. The bigger determining factor for performance is the choice of devices emulated:
The area that VPC and VMWare must improve very much is in the graphics subsystem. The performance impact is big both in VMWare or VPC. The advantage of Virtual PC 2004 (and the reason that makes me like it so much) is the standard hardware emulated: S3 Trio, SoundBlaster 16 and a standard DEC network card. In the case of VMWare, the guest operating system needs a special video driver (SVGA II) to display more than an obsolete 640x480, 16 color display. If you want to run, e.g FreeBSD, you are with no luck.
Virtual PC 2004 isn't the only game in town; there's also VMWare. The key differences between VPC and VMWare are covered in this flexbeta review. As developers, I'm assuming that most of you have access to MSDN Universal, which includes a free (for development, of course) version of VPC. So that kinda makes it the winner by default. Still, it's comforting to know that SymantecMicrosoft has a competitive product in this space.
That's for desktop use. There's also a school of thought on virtual machines for servers-- one that runs contrary to the googlefarm approach. Why not have a powerful server run 5 instances of Windows Server 2000, each blissfully unaware of the other instances?
July 10, 2004
Why Objects Suck
There's been a lot of discussion recently about the Object to Relational mapping problem, which is a serious one. This Clemens Vasters blog entry summarizes it best:
Maybe I am too much of a data (read: XML, Messages, SQL) guy by now, but I just lost faith that objects are any good on the "business logic" abstraction level. The whole inheritance story is usually refactored away for very pragmatic reasons and the encapsulation story isn't all that useful either.A followup from Steve Maine's blog elaborates a bit:What you end up with are elements and attributes (infoset) for the data that flows across, services that deal with the data that flows, and rows and columns that efficiently store data and let you retrieve it flexibly and quickly. Objects lost (except on the abstract and conceptional analysis level where they are useful to understand a problem space) their place in that picture for me.
A typical business problem is the converse of a typical object-oriented problem. Business problems are generally interested in a very limited set of operations (CRUD being the most popular). These operations are only as polymorphic as the data on which they operate. The Customer.Create() operation is really no different behaviorally than Product.Create() (if Product and Customer had the same name, you could reuse the same code modulo stored procedure or table name), however the respective data sets on which they both operate are likely to be vastly different. As collective industry experience has shown, handing polymorphic data with language techniques optimized for polymorphic behavior is tricky at best. Yes, it can be done, but it requires fits of extreme cleverness on the part of the developer. Often those fits of cleverness turn into fugues of frustration because the programming techniques designed to reduce complexity have actually compounded it.
All I can say to the above is, I concur. We've concluded the same thing in a few projects at work. We started with naive Object implementations, and then scaled back-- purely for reasons of simplicity-- to passing around raw DataSets. As one of my co-workers said:
At first you're like "whee! objects!" and then you realize-- hey, this is a lot of tedious, error-prone mapping code I didn't have to write before...I've always maintained that the IDE should be able to support named dot-style access to the database and tables, which it automatically absorbs from the database schema behind the scenes. I know we have Typed Datasets, but those are not transparent and certainly not automatic. So instead of this syntax, which raises the hackles of SmallTalk fans worldwide:
ds.Tables("Customers").Rows(1).Item("FirstName")
We could use this syntax:
ds.Customers.Customer(1).FirstName
Again, this is only useful if it is completely automatic in the IDE, with intellisense support-- that is, zero code required from the developer! It also would force you to have a clean schema design for your DB, which can't be a bad thing.
July 8, 2004
Coding Slave
On Rory's effusive recommendation, I purchased a copy of the book Coding Slave by Bob Reselman.
I have mixed feelings about Coding Slave. It's got a great title, it definitely kept my interest, and it's a quick read. I can also pretty much guarantee you've never read a book like this one.
However, I had a difficult time relating to this book. And no, not because of the rather explicit symbolic sex. I read Coding Slave as the story of a guy from a small business background who was severely traumatized by the world of Large Corporations, Big Six Consulting, and $20 million ERP systems. So much so that he was compelled to write a book about the experience. Part two of an interview at Neopoleon covers this part of Bob's transition in some detail:
When I worked for a Big Six Consulting Company I got to fly all over the US and parts of Europe working in medium and large IT departments in Business and Government. This really opened my eyes to situations and experiences that I never imagined. Prior to Gateway, I had worked for small companies and for myself. There are good and bad points to working small. The bad news is that usually there is not a lot of money around, one tends to overwork, and you can get into real, direct confrontation with people, maybe throw things if under enough stress. The good news is that, for better or worse, you become close to the people with whom you work and can develop lifelong friendships. Things that are food for litigation in large corporations simply don't exist in small companies, age discrimination and sexual harassment suits for example. In my experience in small companies -- and by small I mean companies with ten people -- things are direct, If someone is doing things that you don't like, you can tell them stop it or you bop them in the nose. You don't get sued. And, even if you do get sued, there is so little money around, that if someone wins a case, there is no money to be paid on judgment. People just sort of muddle through resolving offenses: commercial, social, political and sexual.Bob's book deals exclusively with the "fictional" implementation of a "fictional" ERP package by a "fictional" Large Corporation. That's the framework for the narrative arc of the story. Given the depth of raw emotion in the book, I'm inclined to believe it wasn't all that fictional.
I am 34 years old. I currently work for a Large Corporation. I've known many dozens of coders in my professional life-- say, the last ten years-- and none of them have worked on an ERP system of any kind. I am not convinced the ERP world is representative of anything I've ever experienced, or anyone I have ever known. I definitely would not say it "establishes the world of mainstream software development as it stands today", as Rory does.
One thing I did learn from the book is that the entire concept of an ERP software package is itself kind of, well, insane. Quoting from Bob's book:
Ajita and Rafael knew that imposed systems - dictatorships - are doomed to fail over the long term. Systems of the people, by the people, for the people, work better than systems that are imposed on the people. Ajita and Rafael understood that the reason that the MidContinent ERP was blowing up was because it was not designed to serve the people who used it. The system was designed to serve itself only.Freely choosing to design a ginormous, monolithic software package* like this strikes me as a profoundly bad idea-- an idea already tainted by the bizarre mindset of Big Six IT and $20 million ERP packages. No sane organization, even the completely fictional programmer's guild Bob proposes, would build software this way. And certainly a system "of the people, and by the people" wouldn't be written at all-- it would be absorbed from the various open source projects and patched together communally, feeding back into the larger open source zeitgeist.Ajita and Rafael knew that the world needed an ERP that met the needs of the people that used it, made by the people that used it and for the people that used it. Ajita and Rafael understood on that night, on that boat, that their course of action, that the purpose of the rest of their lives, was to organize every coder in the world in order to make a comprehensive software system that worked well enough to make a world in which all coders wanted to live. They also knew that the system they made needed to work for themselves first, because if they could not make an ERP that served the needs of their organization, the code could never meet the needs of any other organization.
And so Ajita and Rafael went about creating that ERP, and every waking moment of every waking day of their lives from that time forward was a day spent making that ERP better. As a result, the primary purpose of the Guild became to make that ERP, which was its one and only product, better. They had the knowledge. They had the talent. They had the desire. They had seen all the horror shows. Now it was time to make paradise.
The Guild named the ERP Justice.
Justice handled all Guild activity: education, compensation, payroll, health care benefits, employment assignment and, of course, membership voting. It seemed as if the members were forever voting on something. Justice handled it with ease.
No Guild member was ever without work. When a member's contract expired or if his job was eliminated, the ERP used its state-of-the-art logic and data-mining capabilities to provide the Guild member with a new assignment that met the exact skills and interests of the member.
A member could work as much or as little as he or she liked. The highest paid software developer was never paid more than seven times the rate of the lowest developer. Pay rate for a job was calculated using a formula that accounted for member competency, status, and job complexity. This formula was reviewed every six months and subject to four-fifths membership approval. Voting took place over the Internet and via cell phones using Justice.
Coding Slave is a hard book to discuss, because it's really all over the map. The book covers so many weighty concepts in a rather thin volume. And this is all in addition to the arc of the story:
- the Offshoring message -- Fuck 'em. Send the code to India!
- the Philosophical message -- Appendix A contains the complete text of Socrates' Meno!
- the Empowerment message -- Charlemagne would have been nothing without his IT scribes! Coders rule the world!
- the Intimacy message -- webcams, porn, sex, suicide, and death! Now with 23% more lesbians!
- the Solution -- Let's form Ye Olde Programmer's Guild!
And then there's the artificially provocative 21-question Quiz, which is also featured in the book.
Coding Slave an entertaining read, but I think the personal character chapter of Code Complete may be a better practical guide for personal development. I'd also argue that the current blogosphere, combined with the open source movement, is a pretty good real world analog for the proposed Ye Olde Programmer's Guild. And it exists today!
To get more perspective on the book, you can hear Bob interviewed on a recent audio show of Dot Net Rocks!. There's also a text interview with Bob on Rory's website in several parts.
* And then calling it "Justice." Ouch. As if there is any, with names like that.
