So I think I am finally ready to come out and say it: programming in Flash sucks.

Unfortunately I haven’t been keeping a list of all the frustrating things about it that I’ve experienced thus far, in order to fully back up that assertion. But I think yesterday afternoon was the final straw for me, and a recounting of it here would seem to make for a good representative example.

I was making some much-needed UI improvements to a piece of the main big project (in Flash 8 ) that I’ve been occupied with the past few months, improvements prompted by the client. I decided to take advantage of the very nifty Drag-n-Drop DataGrid component which was already in use on a couple other parts of the application. The dndDataGrid class extends DataGrid, so that it inherits the whole DataGrid API as it is and then adds the drag-n-drop functionality. It can potentially be a little complex to work with, but overall Judah did a real nice job with it. And the fact that it subclasses DataGrid seems really obvious and sensible.

Well my existing code included a number of functions that operate on DataGrids, and accept a parameter of type DataGrid. Anyone capable of passing the Comp Sci II final I took at UNI knows that in most OO systems, anytime a function parameter or variable is of type A, and class B extends A, any existing object of type B can be placed in variable/parameter A. In most cases/languages, subsequently referencing the object via the variable of type A will make only the A interface available, so class members from class B won’t be accessible, even though the object is inherently of type B. Exceptions to this rule in ActionScript include the use of the square-brackets syntax to exploit the object/array duality that I discussed in a previous post, or when A is a dynamic class such as Object or MovieClip, or when the object in question is a member on an instance of a dynamic class, usually a MovieClip, or when the variable/parameter is declared without a type specifier… ugh! Whatever! The point I’ve been trying to make is that, by one of the basic principles of OO, Abstraction, there should be no reason a dndDataGrid can’t be passed to a function parameter of type DataGrid and subsequently operated on via the DataGrid API.

Well apparently someone didn’t tell this to Macromedia’s compiler. Once I swapped the existing DataGrid for a dndDataGrid, I was bombarded with type mismatch errors.

This really ticked me off of course, but I thought hey, either I’ve uncovered a bug in the works, or ActionScript doesn’t treat class types the normal way I’m used to (I was tempted to go wandering off to the language spec to see which it was), but there’s bound to be a workaround, and the obvious workaround is a typecast. Typecasting is when you explcitly attempt to change the type of an existing variable, and ActionScript is supposed to be able to do this using the NewType(myThing) syntax. If you’re a Flash developer reading this, you probably use it all the time to convert numeric strings to numbers.

So, tedious though it was going to be, I was confident this would solve my problem so I forged ahead with casting my dndDataGrid to a DataGrid in several places where it was going to be passed into one of my old DataGrid-accepting functions. In some cases where I needed several such casts in a row, I used a temporary variable. After some considerable amount of time tracking down every place I would need to cast my dndDataGid to a DataGrid and making the requisite code modifications, I was pretty sure I had it licked.

No dice. Now my dndDataGrid wouldn’t do much of anything.

So I spent a whole bunch more time trying to figure out what had gone wrong. It seemed as if the functions I was passing my typecasted DataGrid to weren’t running. Actually it just turned out, after a bunch more time spent on pursuing this mystery, that they were simply just not operating on my original DataGrid anymore. Rather than cast my original dndDataGrid into a DataGrid, my typecasts were actually allocating a whole new DataGrid in memory (though not on the stage) and my functions were receiving that DataGrid instead. It would appear that Macromedia’s idea of typecasting is just to pass the to-be-casted object to the class constructor, where its properties are copied. Which for most purposes is basically useless.

So the only remaining solution was to remove the type specifications from all the function parameters intended to receive DataGrids. After, of course, tracking down all the so-called “casts” I’d added and undoing them. In the end, I was forced to revert to weak typing. Eventually I got the dndDataGrid populating as I’d intended and was able to drag rows out of it, but after wasting my afternoon wrestling with a busted-ass type system, I didn’t have time left to actually implement the feature that the new drag-n-drop aspect of the UI was intended for.

That complaint made, there are some signs that the Flash programmer’s world is getting better. From alternate IDEs and programming tools to whole different compilers and languages, there are quite a few options for those who’ve become disenchanted with what they’ve been working with.

It just so happens that I’ve been looking into some of these alternative tools in recent days. Flash 8’s IDE has its good points, especially for UI designers, but overall really just isn’t cut out out for these larger projects. I’d been using FlashDevelop quite a bit, but mostly as a very fancy ActionScript editor; I still went back to Flash to build and test my .swf’s. I hadn’t had a change to learn some its cooler features. I still plan on working through these tutorials someday soon.

I also started messing about with Eclipse, and what’s called FAMES (I think it’s an acronym for the various programs and Eclipse plugins involved. They like to swim in alphabet soup over at OSFlash). I’ve tried it a little but ended up mostly using it as an ActionScript editor so far. Actually, I did use the local history once, and I liked the SVN integration. FlashExtensions has some pretty good beginning-level Eclipse video tutorials, and Eclipse’s own help files (Getting Started and Concepts) are quite helpful and readable. I’m still working on it.

The thing that thus far has kept me from really making full use of these tools however, is that I’ve yet to manage to successfully compile anything with MTASC. It’s a command-line compiler, which is fine if you like issuing console commands to compile your .swfs, but even more a good thing for the fact that, by virtue of being a command-line program, it allegedly integrates nicely into either Eclipse or FlashDevelop. I also suspect that it gets the type system right, or at least better, but I don’t yet know this for sure. One thing that’s often repeated is how much faster it is than Macromedia’s compiler. It’s also worth noting that they had the good sense to write it in OCaml. I tried it in Eclipse using Flashout, but like I said, have yet to get it to work. Here’s what the deal is: supposedly the code in Macromedia’s core and mx classes is so bad that it needs to be patched to be MTASC compatible. Thinking about that after yesterday’s experience makes me snicker a little.

Here’s what’s been holding me up, though: in trying to apply the aforementioned core classes patches, patch would error out partway through applying the mx patches, with a “File Exists” error. This is a pretty disintuitive error message, after all I can’t very well patch what doesn’t exist. It had me flummoxed for a few days until I thought back on when I hand-applied Patrick Mineault’s patches for the Flash Remoting classes. Yeah, some of the lines he has you patch were pretty gronky. The kind of gronky that’s wrong but works anyway, at least with Macromedia’s compiler ;) More importantly, FlashDevelop prompted me with a “this file is Read-Only, do you want to save it anyway?” message. I put two and two together and finally realized that the {wherever}/mx/remoting folder must have its read-only attribute set. Turned out I was right. I think the Flash Remoting components install it that way by default, and the attribute carried over to the new copy of the classes folder I made to apply the patches to. I re-copied the original mx folder in place of the half-patched one, opened it up, right-clicked the remoting folder, unchecked the read-only box, and ran the patch again. It made it all the way through except for one class it warned me about where one of the patches was in the same place as one of Minealt’s. Probably the same change. Hopefully it works, whatever file it was :-\ Anyway, now that I’ve got the patches applied, I’ll be giving FAMES another go.

Of course there’s yet another option out there right now for Flash-targeted development, and that’s Flex. But it’s getting plenty of publicity lately so I don’t have to tell you about it. I haven’t had the pleasure of trying it out yet. Soon, soon.

There’s a third way too, and it’s called haXe. I’d been meaning to look into it. It’s a language rather like ActionScript, but different in some promising respects. One recommending factor is that it’s brought to you by the same guys behind MTASC. Also, it’s able to compile into Flash, JavaScript, or bytecode for the mod_neko Apache module’s virtual machine for database access and all that good server-side stuff. In other words, where we’re used to using a melange of languages (ActionScript, PHP, JavaScript) haXe lets you write the whole app in one language. haXe compilation can be directed by .hxml files containing compiler directives, and it looks like you might even be able to use them as entire build scripts.

A couple days ago I got wind of haXe’s 1.0 release, so I installed it and worked through a couple of the Getting Started tutorials pertaining to haXe/Flash. But what really caught my attention about haXe came when I read through the language reference. Namely, the type system. haXe is strongly typed by default, and yet also appears to be highly flexible and strongly OO. You can tell it’s influenced by OCaml and perhaps a bit by Ruby. It has type inference, generics, and a full “enum” variant-record type. Go and check it out. If it can use v2 components, I’m sold. Of course, then I’d have to sell the concept to my employer ;)

Flash programmers today have more options in terms of language, compiler, and IDE than ever before. Many of them are open-source tools that embarrass some of Macromedia’s own stuff, at least their older stuff. It seems like an exciting time to be in the Flash game.

Update 2:10 pm: Found a nice (despite copious typos) video tutorial on setting up and using Eclipse/FAMES for flash development here.

Update 8:35 pm: Earlier today I got something to compile in FAMES… namely the example from the above video tutorial. I had to change a couple of lines in the example’s code because MTASC didn’t like certain things like assigning a number to a text field’s text property, but derned if the thing didn’t manage to sit there and count to 1000 right inside of Eclipse.

One thing I came to really enjoy about ActionScript while I was working on a recent large project at work is that objects, even ones instantiated from classes, can be treated just like associative arrays, indexed by the strings matching the names of their member variables and functions.

ActionScript doesn’t enforce strict encapsulation of data and functions designated as private – you can still get at private members, you just have to do it through the square-brackets operator (myObject[“name”]) rather than the dot operator (myObject.name). This also gives you the freedom to dynamically determine the name of a class member (data or functions) that you’re after, so you can take advantage of this by naming things in a class (or instance names of user interface elements in a .fla on which your class runs) according to some sort of convention, and then do things like, say, determine which of several functions to call at runtime like “myObjectexpression-that-evaluates-to-string-name.” Leave off the parenthesied argument list, and the expression returns the function itself.

This is just one of the nifty effects of the “object/array duality” that ActionScript shares with its older brother JavaScript, and which they both get from their common language spec, the ECMAScript Specification. It is this feature along with first-order functions that makes JavaScript’s and ActionScript’s prototype-based object systems possible, and ActionScript’s second, class-based, object system is actually syntactic sugar that gets translated into prototype-based code at compile time. You can use the features of both in combination to do some really cool things.

Also, in both languages, the literal associative-array syntax – a series of keys and values, paired up with colons, separated by commas, between a pair of curly braces – can be used to instantiate literal objects, and this idiom has become more popular among JavaScript coders in recent years with the AJAX craze. Thus today I came across this blog post on the subject, which prompted me to think about the object literal, which I’ve only thus far used to make simple associative arrays. They’re often used to add items to List-based components like ComboBoxes – each item is supposed to be an object containing a label field and a data field, and it hadn’t occurred to me before that the data field could really be anything, including a function. I guess I did nest another (numerically-indexed) array there on one occasion…

It occurred to me that this syntax can also clean up certain code and make it much clearer to read. In many ActionScript examples I’ve downloaded to help me learn to accomplish certain tasks, I’ve seen a common idiom of instantiating a new Object for the purpose of using it as a listener for events fired by some thing:

[code lang=”actionscript”] var myListenerObj:Object = new Object(); myListenerObj.someProperty = someValue; myListenerObj.onSomeEvent = function(evt:Object) { doStuff; } myListenerObj.onSomeOtherEvent = function(evt:Object) { doOtherStuff; } myEventChucker.addEventListener(myListenerObj); [/code]

Among ActionScript coders of the “nested functions are evil” school of thought, it’s phrased this way:

[code lang=”actionscript”] var myListenerObj:Object = new Object(); myListenerObj.someProperty = someValue; myListenerObj.onSomeEvent = someFunction; myListenerObj.onSomeOtherEvent = someOtherFunction; myEventChucker.addEventListener(myListenerObj);

function someFunction(evt:Object) { doStuff; }

function someOtherFunction(evt:Object) { doOtherStuff; } [/code]

Which is syntactically fine, and works so long as you don’t have some other variable that those functions need to be closed over to dynamically effect their behavior… but which I think is less desirable in certain respects: you’re probably declaring a function in one class that you only intend to use on some other object entirely. This is not clear from the code, especially since there are typically a lot of other lines of code in between where the functions are declared and where they’re attached to the listener object. So you have these functions hanging around cluttering a class where they don’t really belong – both in terms of code and in terms of memory, since a new function is allocated when you assign them to that listener object, so now you have extra copies of this function, that you never intend to be executed. Ironic, since the usual justification for “nested functions are evil” is memory waste.

The object literal gives us a much nicer way to get this job done: [code lang=”actionscript”] myEventChucker.addEventListener( { someProperty: someValue,

      onSomeEvent:
           function(evt:Object) {
                doStuff;
           },

      onSomeOtherEvent:
           function(evt:Object) {
                 doOtherStuff;
           }
  }); [/code]

It’s much clearer here what’s going on. Your listener object is all right here in one place. Not only that, it alleviates the confusion of ActionScript 2.0’s “scope bug” that I’ve talked about before: the scope of those two functions is clearly visible as being between a certain set of curly braces. And there’s a lot less repetitive keyboard-mashing involved in typing it, which as a sensibly lazy programmer I love.

Update: Apologies if any of the example syntax above isn’t quite making sense. I seem to be sort of mixing up the “on”-function method with the EventListener method. addEventListener takes as an argument the event name as well as the listener object, and the events don’t always start with “on.” The basic concept behind the above still holds.

Over at Joel On Software, Joel has been taking nominations and votes from readers for articles to be included in his second edition of The Best Of Software Writing. I swung by for a cursory look, which is about all I’ve had the time to do thus far, but happened upon this piece called “Why Good Programmers Are Lazy and Dumb.”

I noticed to my delight and reassurance that I recognized some of the qualities discussed in that piece in myself. I have a very current example of my useful laziness, from work (hopefully I don’t get in trouble at work for posting these code snippets – they’re nothing special). I recently had to debug some ActionScript on the Big Project I’ve been working on for the past couple months, that was written by one of the other programmers on the project who had left the company. Said person was one of our lead programmers, who handled pretty much all the server-side logic for this project himself, and I very much enjoyed working with the guy. All the same, code like this, particularly in a language as flexible as ActionScript, kind of bothers me. In the class for a page where customers fill in their billing and shipping info, there was this code to fill in the TextInput and ComboBox components with data from a shared object:

[code lang=”actionscript”] billFirstname_txt.text = billing_so.data.billFirstname; billLastname_txt.text = billing_so.data.billLastname; billStreet1_txt.text = billing_so.data.billStreet1; billStreet2_txt.text = billing_so.data.billStreet2; billCity_txt.text = billing_so.data.billCity; billState_cb.textField.text = billing_so.data.billState; billZipcode_txt.text = billing_so.data.billZipcode; billCardName_cb.textField.text = billing_so.data.billCardName; billCardnumber_txt.text = billing_so.data.billCardnumber; billExpirationmonth_cb.text = billing_so.data.billExpirationmonth; billExpirationyear_cb.text = billing_so.data.billExpirationyear; billCardverification_txt.text = billing_so.data.billCardVerification;

shipFirstname_txt.text = billing_so.data.shipFirstname; shipLastname_txt.text = billing_so.data.shipLastname; shipStreet1_txt.text = billing_so.data.shipStreet1; shipStreet2_txt.text = billing_so.data.shipStreet2; shipCity_txt.text = billing_so.data.shipCity; shipState_cb.textField.text = billing_so.data.shipState; shipZipcode_txt.text = billing_so.data.shipZipcode; [/code]

And later, in another function, the following code to pull the contents of the input form back into the shared object before loading up the order confirmation page:

[code lang=”actionscript”] billing_so.data.billFirstname = billFirstname_txt.text; billing_so.data.billLastname = billLastname_txt.text; billing_so.data.billStreet1 = billStreet1_txt.text; billing_so.data.billStreet2 = billStreet2_txt.text; billing_so.data.billCity = billCity_txt.text; billing_so.data.billState = billState_cb.textField.text; billing_so.data.billZipcode = billZipcode_txt.text; billing_so.data.billCard = billCardName_cb.selectedItem.data; billing_so.data.billCardName = billCard_cb.textField.text; billing_so.data.billCardnumber = billCardnumber_txt.text; billing_so.data.billExpirationmonth = billExpirationmonth_cb.text; billing_so.data.billExpirationyear = billExpirationyear_cb.text; billing_so.data.billCardVerification = billCardverification_txt.text;

billing_so.data.shipFirstname = shipFirstname_txt.text; billing_so.data.shipLastname = shipLastname_txt.text; billing_so.data.shipStreet1 = shipStreet1_txt.text; billing_so.data.shipStreet2 = shipStreet2_txt.text; billing_so.data.shipCity = shipCity_txt.text; billing_so.data.shipState = shipState_cb.textField.text; billing_so.data.shipZipcode = shipZipcode_txt.text; [/code]

Now really, come on. I mean, this guy has a Master’s in Comp Sci and at least a good ten, maybe twenty years’ experience on me. You’d think he’d know better (and I’m not talking about setting a ComboBox by setting its textfield either – though there’s a potential bug with that). But, as corroborated by the fact that he often stayed and worked late hours and VPN’d in from home on weekends, the guy needs a lesson in laziness. What lazy programmer would want to have to type code like this in the first place – Even with the benefits of copy-paste, it’s terribly tedious – much less have to maintain it later? I decided to expend a moderate effort to save me work in the future: I added an instance variable (var fieldNames:Array) and initialized it thusly in the constructor:

[code lang=”actionscript”] fieldNames = [“billFirstname”, “billLastname”, “billStreet1”, “billStreet2”, “billCity”, “billState”, “billZipcode”, “billCard”, “billCardName”, “billCardnumber”, “billExpirationmonth”, “billExpirationyear”, “billCardverification”, “shipFirstname”, “shipLastname”, “shipStreet1”, “shipStreet2”, “shipCity”, “shipState”, “shipZipcode”]; [/code]

Now I would be able to do either of the above operations by looping through this array It just so happens that the TextInputs and ComboBoxes have names that match their field names in the shared object (the contents of which eventually gets inserted as a database record – ideally, the field names should match there too). Even accounting for the fact that some of the inputs are TextInputs while others are ComboBoxes wasn’t really that bad. Note also, that I also created another variable, theRecord, to hold the information being “edited”; this was also done for lazy reasons, to take advantage of some methods I had already in a superclass; plus it has the side benefit of allowing the user to undo all changes, should need to implement such functionality later on.

So here’s initializing from the shared object:

[code lang=”actionscript”] for(var i:Number = 0; i < fieldNames.length; i++) { theRecord[fieldNames[i]] = (billing_so.data[fieldNames[i]]!=undefined) ? billing_so.data[fieldNames[i]] : “”; } updateDisplay(); [/code]

Where updateDisplay is a slightly modified override of something I already had, inherited from a superclass, and looks something like this:

[code lang=”actionscript”] private function updateDisplay() { for(var i:Number = 0; i < fieldNames.length; i++) { var propertyName = fieldNames[i]; if (this[propertyName+”_txt”] != undefined) { this[propertyName+”_txt”].text = (theRecord[propertyName] == undefined) ? “” : theRecord[propertyName]; } else { this[propertyName+”_cb”].selectedIndex = (theRecord[propertyName] == undefined) ? 0 : findItemInComboBox(theRecord[propertyName], this[propertyName+”_cb”]); } } } [/code]

As for findItemInComboBox, that’s just another silly little function I had already written and was inherited here from a superclass, and suffice it to say it simply searches the given ComboBox (second argument) for the item whose data field matches the first argument, and returns its index. Nothing fancy there either.

The operation of repopulating the shared object from the inputs – or from theRecord after first copying the inputs theRecord – needn’t be duplicated here either, it’s pretty predictable variations on the loops above.

In summary, I basically made the code less tedious to read and/or work on, and even enhanced its functionality slightly. All by trying to avoid having to work too hard on it in the future. Out of “laziness.”

And of course, the best part is, should yet another input field need to be added to this form, all I’ll need to do is add its name to that fieldNames array, and chances are, it will already work, without having to pore through the rest of the code looking for other places where it’s mentioned. Now that’s lazy.

I’m a little bummed out that Dave hasn’t been back to discuss IT/software offshoring since my last post. He’s a smart dude and always interesting to get into these kinds of discussions with. And blogging is so much more fun when it isn’t one-sided. I don’t post a lot of comments on other sites, but I love reading comments other people leave when they get really into a subject. I’ve often wondered why Wallingford doesn’t enable comments on his site. He has his reasons and he’s posted about them before, but I don’t remember them.

Anyway, I’ve run across a couple more articles that I think relate to the subject that I’d like to share. Economics professor Robert Lawson posts at Division Of Labour the text of a talk he recently gave at the National Summit of Chief Executive Boards International. It doesn’t address the IT or software industry specifically, but rather two major trends facing American businesses, globalization and customization. Briefly and at a rather high level of abstraction, Lawson basically concludes that American businesses that are aware of these trends and that can use that knowledge to their advantage, operating in the American free-market economy, will be successful, and that the trends will continue to improve the standard of living of Americans as a whole.

He touches on an interesting point that I’ve heard echoed elsewhere, which is that the kinds of things being outsourced tend to be those that are more standardized, while American workers will increasingly be involved in more customized products and services. This makes sense from the standpoint of a U.S.-based company; work on things that are more standardized is probably easier to manage from afar, and the trend does seem to be for standardized assembly-line kinds of processes to go overseas. I’m kind of riffing here, but I suppose that for web applications this means that if what you need is YASC (Yet Another Shopping Cart), getting it done overseas is a really good idea and will probably save your company some cash, provided you’re willing do what it takes for the different kinds of management challenges required.

It would seem that the company I work for is increasingly moving into custom web applications for specific kinds of businesses. The project I’ve been involved with lately provides photo studios who have their processing done at a particular lab with an interface that is integrated with a portal where customers can order prints. A fair amount of the company’s business in the recent past has been a bit more standardized, producing web sites for banks. We can generally knock these out pretty quick now, but we do continue to innovate in the features that these sites provide; and really, it was a key innovation by the company’s founders, a Flash-based content management system that allows clients to edit their site without having to go to the web design company to do every little routine update, that got T8 off the ground. It really addressed a very common problem that started in the 90s Internet Boom, one that always bothered me a lot, where suddenly everyone had to have a web site, but not everyone had the ability to maintain their site’s content and a lot of sites got stale. Anyway, now I’m just kind of advertising… ;) But I think you get the idea.

The other article that came my way was via the ACM TechNews mailing list. It mainly had to do with this Newsweek article, which seems to contradict a little of what I was just saying about the kinds of work that is offshored. Companies are increasingly opening up R&D centers in places like India, and yet this is apparently not hurting the tech job market in the US. The doom-and-gloom propositions of the outsourcing backlash seem to have been disproven, and instead it would seem that the cost savings have fueled more growth in the industry, both overseas and domestic. According to the article, “American companies are hanging on to the high-skilled work that requires face-to-face interaction, while everything that can be done ‘over the wire’ gets shipped offshore.” This definitely jives with some major points in Dave’s comment. T8 seems to pride itself on that face-to-face aspect, and for good or for bad, I’ve found that I’m communicating directly with clients quite often. Overall this doesn’t bother me and sometimes it’s really fun. But that certainly doesn’t mean that my job is turning into all customer service and no coding, either. My core skills and duties are still very much in the technology.

Actually, I think the more interesting part of the ACM article was its link to an ACM paper, “Globalization and Offshoring of Software–A Report of the ACM Job Migration Task Force,” which examines the subject in much more detail, and which I’ve admittedly only had time to read a portion of so far. Generally though, its conclusion echoes my speculation in the previous post that offshoring is growing, but the industry as a whole is growing at least as fast.

I think Dave and I agree that the outsourcing backlash was greatly exaggerated and that the overall outlook is positive. Where I think I part ways with him is that it seems as though he is predicting that the U.S. will become a country full of managers, with all the down-and-dirty techie skills going elsewhere, and that a solid Computer Science education should be far less a priortity for universities and students than one in business, management, and customer relations. Creating a custom product for a client takes both, and American IT workers will definitely be expected to have a mixture of the two in the future. Dividing the two up into different classes of people is in my opinion potentially disastrous, particularly when one of those classes will be thousands of miles away from the other. And plenty of people in this industry can attest to the problems of being managed solely by people who have no understanding whatsoever of what you do. While one can’t expect anymore to be able to just hide away in a cubicle and crank out the code and have nothing more expected of them, likewise no one should expect that focusing on the kind of understanding that one gets from a core Comp Sci curriculum, and that enables one to produce quality software code, is going to mean that they are going to be stuck without a job because of outsourcing.

Dave has quite welcomely appeared to pipe in on one of his seemingly favorite topics, the hiring of overseas programmers. “Outsourcing” or “offshoring” or whatever term you want to use became a politically charged topic in recent years; I tend to observe that most of the jobs getting offshored are the boring jobs anyway, like call center gigs. But there’s definitely a trend toward hiring programmers in other countries, particularly since the price tends to be right. Everyone has an opinion on this trend.

The first part of the discussion is on the where have the little coders gone? post from a couple days ago, but as I felt the topic was veering a bit from that of that post, I thought I’d put up a new post to continue this line of discussion on. So if this post seems a little less thought out ahead of time than usual, it’s because it’s picking up in the middle of a somewhat off-the-cuff discussion. Of course, anyone can jump in.

I’d like to pick up by tossing out some input of my own on a couple bits from Dave’s most recent comment. Mind you, I’m not going to be one of the many that try to infer that code produced by overseas programmers is in general of lesser quality. It may or may not be, but I don’t have the experience personally to back up a statement. And I’m not working from those tired political talking points, with their little twinge of veiled racism, so commonly aimed at scaring American workers. The same kind of attitude behind those lines of thinking often comes into play in the other direction too, in the form of a stereotypical conception that American workers are lazy and maybe kinds dumb and demand too much money, while Indians and Asians are all a bunch of super-industrious, buttoned-down genius code-producing robot-people. So right off the bat I’m declaring my intention to avoid those pitfalls. As far as I’m concerned, talent is talent regardless of what country it’s in, and it can be found everywhere.

The problem for american students (and the colleges for that matter) is that these overseas doods will continue to push the hourly rate down

True that. But I’m not really comfortable with looking at programming, or its products, as a mere commodity, in the sense that commodities are price-driven. Most kinds of work and product that require skill or processing beyond the raw-materials stage are not commodities, and require more complex and nuanced evaluation than simply what is cheapest.

Software is especially tricky to quote a price on, as the high tendency of projects that run considerably over budgets and deadlines illustrates. (Improved methods in project management promise to help this long-persistent situation, but if anything this actually plays more into my points about the necessity of project management personnel to also be coders, and the benefits of skill and experience).

Managing a project staffed by overseas workers has other costs, difficulties, and sometimes headaches associated with it, including the predictable things about time zones, communication, language, idiom, culture, etc. It can be harder to judge the quality of workers you can’t spend time with in person. There are a lot of ways in which an “offshored” project is just different from an onshored one, and management at any company that intends to offshore software work needs to do their homework on this and be prepared to take on the different responsibilities.

Yesterday’s The Daily WTF has sparked some interesting discussion on just this sort of thing, and most points we could make here have probably already been made by someone there. The post is about a single very simple, but very stupid and very costly, coding mistake in an offshored project that wasn’t caught until the system was already in use, and then caught by “onshore” developers called in to look into the bug. One can make a case that it would likely have been caught early were the development being done in-house; it is also arguable that the culprit is something else entirely, and good points are being made in both directions there.

There are also sneakier things: when I started at my current company, our CTO warned me to be a little bit careful about working with a programmer in our company who is from India, saying that from working with her and a previous Indian employee (both of them live, or lived at the time, in the local area, though whether as citizens or on visas or whatever, I don’t know), he had come to understand that something having to do with Indian culture causes them to be very sensitive about other people changing or picking at their code, and they had become very offended and upset when it would happen. Thus one might expect that code inspection/peer review, an important component of software engineering, might be a bit problematic with Indian workers. In any case, I think the co-worker he was asking me to be careful about has adjusted somewhat since then.

Hiring temporarily on one-shot projects also means that the developers, offshore or on, have a different motivation. They’re not going to be thinking long-term about your company and will thus be considerably less focused on producing maintainable code or reusable components that future projects can benefit from (at least not your future projects), than on cranking something out fast that will look impressive at the moment when it’s brought to the client. A very high proportion of projects going overseas are on this kind of temporary one-project basis. I kind of doubt that companies have developers spending time mining offshored code for stuff they can reuse, and I’m not going to pretend to have any idea what intellectual property issues may come into play in such a scenario.

I think the entry level job market (where joe-college-grad is mostly likely going to start) is on an irreversable shrinking trend.

Proportion-wise I would agree – a larger proportion of entry-level software gigs may be going outside the US. But I think the industry as a whole is very much on a growing trend that will likely balance it. Another balancing force is the lure of those overseas personnel to move to the U.S. where they can do their same job for higher pay and more benefits in better conditions.

I’m probably a little out of touch with what comp sci kids are into now, but when I was in school, everyone fancied themselves a web-based person (whether or not the school taught it)

I don’t know that the attitude is all Web nowadays – I think there is considerably more interest in embedded systems, robotics, and computing for scientific research (especially this “bioinformatics” thing) than there was during the Web hysteria of the 90s. For end-consumer software products however, I think the Web is very much where the future is at, and more applications that people purchase and house on their own PCs will be moving to the Web. It’s a trend that is definitely in its early stages but that I think is very much on the ascendant. I think one day most people won’t even need their own computer for mundane everyday things like email and word processing anymore, and will instead use lighter-weight, cheaper client devices to access applications and files on the Web from any location with an Internet connection. But then, I have been saying for some time that the masses of home users, on the whole, currently have much more computer than they need or in most cases can handle.

I’d hazard a guess all the COBOL and ADA kids are probably safe since its not too likely Rockwell Collins will be shipping sensitive programming gigs out to the mid east

Yeah, defense contracts are probably safe. I think I’ve even heard that the defense sector is one of the fastest growing parts of the US software industry. Certainly it’s where a lot of the cool action is – I took a tour of the University of Minnesota a while back and was very impressed with the robotics stuff they were working on for military applications.

As an aside, I find it interesting that you phrase so many sectors of the software industry in terms of programming languages. “The COBOL and Ada kids,” “A badass ColdFusion programmer.” I really feel programming languages are orthogonal to this subject – if Rockwell Collins started writing in Haskell (which might not be an altogether bad idea), I don’t think it would change the kind of business they are in. More to the point, it bothers me categorizing programmers by languages. Any kid that goes into college thinking that whatever programming languages are taught there are the ones that they will make a career out of using, is in serious need of a reality check. I don’t think anyone would have considered me “an ActionScript guy” when I started my current job; rather I got a job that demands ActionScript so I learned it. It was really my goal in pursuing my Comp Sci education that I would not become language-dependent, but rather that I’d learn the concepts and theory that cut across programming languages so that whatever language is needed for the job I’m doing, I’d be able to learn it. Sure as you don’t see a lot of jobs for Algol and Pascal programmers these days, just being able to do Java and/or Ada is only going to take you so far; young folks still in or just out of college who can’t be bothered to pay enough attention to knowledge that will enable them to keep with changing times, trends, and languages, will be the next generation’s equivalent of that breed of old dinosaur stuck-in-their-ways COBOL programmers you hear so many jokes about these days.