Windows 7 font fix

While using Windows 7 one day, I uninstalled a Google program (Google Earth, I think), and then all of my fonts were permanently italic, everywhere. I worked around this by following a tip from another user on a Google help site and installing arial32.exe every time I booted into Windows, which apparently reset something that got removed, but it would only last until the next reboot. That got tiring and didn’t work on everything, so I tried to make the fonts normal again.

I found a font fix for Windows Vista that looked plausible and applied it. Well, that didn’t go over well. All of my fonts were now broken, and I just got little squares and weird things. After trying to trawl through the registry and undo the fix I’d applied, I settled that I would need to do a repair installation.

So I put in the install disc, rebooted, and found out that at least on my disc, you can’t really do a repair installation. That was a waste of time and really lame. Do other Win 7 discs lack a repair install?

I tried to install PowerPoint Viewer because someone said that it contained all default Windows fonts. I’d hoped it would restore the registry keys. It didn’t. If you have deleted your actual fonts, this still might help, but it won’t fix registry problems.

Then the idea came to me that I had a Win 7 install in a virtual machine, and that I could grab the font keys from there and hopefully that would undo the big evil Vista fix as well as the italics problem. I exported the keys from the VM and applied on the native install, and it worked! :D

I’m attaching the registry fixes to this. If any of you have these problems with a Windows 7 install, remove:

  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontMapper\FamilyDefaults
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes

and then apply win7_font_fix, which will restore Windows’s default font settings and fix things like permanent italics.

Of course, you should make always make a backup before you change the registry and I claim no responsibility for damage this fix may cause. This fix is not supported. Use it at your own risk. I hope it helps some people.

Once again, the link for that is win7_font_fix.

Posted in howto | Leave a comment

Writing a good job ad for a programmer

As a poor person, I have been perusing a lot of job ads recently and I’ve run into several major turn-offs over and over again. I don’t reply to ads that seems clueless because I have learned through sad experience that working somewhere lame is not an acceptable activity in life, and if an ad is clueless, it’s likely that the company behind it isn’t too hospitable to programmers, however well-intentioned that company might be. As such, I am writing a brief howto regarding job ads, designed to help you find and retain good programmers.

Avoid colloquialisms

The words “rockstar”, “ninja”, “guru”, and so forth are instant deductions. If the rest of your ad sounds pretty great, these words might be reluctantly overlooked, but in an average ad, they kill all potential of a reply.

Why should that be so? Don’t these ads demonstrate your company’s hip-funness? No, they don’t; they demonstrate that your company is an out-of-touch poser, trying to wow people into thinking you’re a good workplace with “unconventional” and evocative language, but programmers aren’t so easily fooled. If you want to prove that your company is cool, prove it by describing cool things about your company, like “free lunches” or “work when you want” or whatever good things your company does. If you’re a run-of-the-mill company that provides no special benefits to its employees, you probably should just focus on the coolness of the tech you use and other micro-desirabilities about the job you’re trying to fill.

Now, it’s bad when a company is using these words to conform to the norms (saw an ad today that said “…a rockstar (everyone else is using it, so we thought we would too)”), but it’s worse when a company actually means it and expects “rockstar” or “guru” performance of the candidate. In all cases where I’ve found this, the expectations have been completely unrealistic in way or another, whether it’s the expectation to hire “rockstars” with a salary of $50k or the expectation that “rockstars” can perform the work of five plebes. These expectations are unrealistic; it seems that people think programming can get done like magic if you just hire the right guy, but the fact is that substantive programming has been and always will be hard work, even for the geniuses among us, and it will take time to write programs, and your programs will have bugs, no matter how insistent your demands or how diligent your search for the mythical “rockstar”. And, supposing you could find a person like this, they aren’t going to sign on for the meager salary you’re offering.

This is also applicable to a lesser extent to the term “expert”; “expert” is so widely used that you can’t really take points away for it, but it’s not ideal, because almost any normal coder knows that the experts in a certain language are the ones writing the VMs and compilers and designing the language’s future, and in almost every case, you’ll never find such a programmer in your respondents. There’s nothing wrong with that, we can’t all be experts in everything; Guido van Rossum is an expert in Python, but (as far as I know) he’s not an expert in .NET. If you want a Java programmer, you just want someone who knows it well, not someone who would consider themselves an “expert” because if these people are serious and consider themselves experts and can’t point to several patches to a language runtime or compiler or some other substantive low-level work on the subject, they are more trouble than they’re worth.

So, just leave out all the colloquialisms. If you’re looking for a good programmer, say something like “Looking for a Good PHP Programmer”, “Must be good at PHP”, etc.

Act like a normal person

Programmers hate pandering. Write your ad in prose and seem like a person well-informed on development. Keep things simple; as programmers know all too well, complexity is a death knell. When you bring a candidate in for an interview, don’t be stuffy or overly “corporate”; just relax and talk with the guy, because you’re a person, and he’s a person, and you’re all just people, and that’s all there is to it, there is no reason to bring other things in.

Don’t gush on and on about your mission statement or other silly things in the ad or interview, just be straightforward; instead of corporate-speak “We provide a cacophony of solutions to help businesses around the world pervade their markets”, try “We sell a few marketing-related services to businesses”. It’s simple, to the point, and you don’t look like a corporate drones.

Programmers spend all day with logic and if you do something illogical they will notice and resent it. Policies that exist for no reason and other corporate trademarks like big-wording prospective clients to death to make them think you’re smart is anathema.

Offer a decent salary

Around here, most people seem to think that software developers aren’t worth any more than $45,000/yr. It’s hard to find jobs that offer more; there are some senior-level positions, but by and large, the majority of ad are going to seriously lowball their targets. I guess that they must be getting some respondents that way, but it’s not a good way; you’ll get people too desperate to care or too ignorant to know that their work is worth much more, and these aren’t the serious professionals you’d want running the infrastructure that supports your business.

Just think about the responsibility and power that your programmers hold. You need to make sure you get trustworthy and experienced professionals in there; they have access to all of your customer data, both stored in databases and at point-of-entry, including credit cards and passwords. In most cases, they have access to all of your sales data and can tell the performance of the company with a simple SQL query. In some cases, they may have access to salaries, SSNs, and other confidential employee data. It is their job not only to safeguard the integrity, security, and usability of this data, but also to write the programs that use it. That is a lot of power. I don’t know what it is, but a lot of businessmen seem oblivious to that. There is no reasonable way to keep a programmer out of these databases and systems.

As such, it’s pretty important to keep your programmers happy. Programming is serious and complex business. When a programmer with business and domain knowledge quits, you lose a lot; it takes several months for competent programmers to get to know your systems very well. Programmers should be both feared and honored.

What does that $45k salary say, and what do you think you’re getting away with? Most professionals can find much better salaries, so what does that leave you with when you offer $45k? And do you trust those people with these responsibilities?

Don’t be a recruiter

Recruiters are almost universally clueless. They have little education and they don’t understand any of the technical fields into which they pump candidates. I’ve seen many come from Robert Half and friends who pass the little trivia exams they give before they send you out and are absolutely useless on the job. These people come in because people who don’t understand programming can’t tell which programmers can actually sit down and write some programs and which memorized a few simple syntax rules and survive by globs of copy-pasted functions.

I never respond to recruiters anymore, ever. They always bring you in for an interview and it never leads anywhere because they can’t tell what anything is or means, all they can do is compare resumes. These comparisons have, with one exception, resulted in completely non-sensible matches in my case specifically. In short, recruiters a giant waste of time for everyone involved; the candidates they provide can rarely perform the actual work that needs to be done and the programmers that respond are usually spammed and dragged through a lot of useless crap to no benefit.

Just don’t use recruiters.

Example

Here’s an example “good” job ad, which I’ve just made up.

My name is Jeff Cook. I run a company called Deseret Technology that provides general IT consulting services, primarily custom development. We need an experienced .NET developer and prefer experience with ASP.NET MVC. We are offering [some decent rate]. Please contact me at [email] and we’ll talk about it.

Here are some awesome things about our company: everyone carpools in a giant blimp that picks you up at your house every morning, there are fresh tacos under all the keyboards, our employees have all types of haircuts, and we are just some pretty smart dudes.

See? Not so hard. The answer lies in simplicity; it’s just basics, really. Be smart and everything will work out great.

Posted in Uncategorized | Leave a comment

Facebook doin’ it wrong

Above is a picture of Facebook doin’ it wrong.

This is what happens when you leave yourself logged in too long, this is the “timeout” screen. You can notice its utter uselessness by observing that all around it is your friends’ confidential data, intended only for those approved to see it, not to mention some information about your own account.

That means if you leave this up at a computer lab, while Facebook will cause your session to die, which is good, they’ll leave your newsfeed containing arbitrary private data on-screen, which is really, really bad.

Even more hilarious is the “cancel” button, which causes this dialog to disappear and the one post obstructed by it to become visible.

Imagine if your bank did this.

Posted in design, security, whining | 1 Comment

Add player stats to scoreboard in sauerbraten/cube2

We all like sauerbraten, but I wanted a persistent look at my stats as I played. As such, I have written the following patch to display relevant info. Thanks to #sauerbraten for help.

This works against stable, “Trooper Edition”. There is a patch for SVN floating around out there somewhere, which includes flags captured as SVN has that variable implemented and I didn’t feel like backporting it. Hopefully there will be a release soon and it will be moot.

So, just apply this from sauerbraten/, not sauerbraten/src.

diff --git a/src/fpsgame/client.cpp b/src/fpsgame/client.cpp
index ca44789..35ff80d 100644
--- a/src/fpsgame/client.cpp
+++ b/src/fpsgame/client.cpp
@@ -1069,6 +1069,12 @@ namespace game
                        *actor = getclient(acn);
                 if(!actor) break;
                 actor->frags = frags;
+                //we should be able to get teamkills from the server somewhere
+                //because the server tracks them. right now we will track them ourselves.
+
+                if (actor==player1 && isteam(actor->team, victim->team)) {  player1->teamkills++; }
+                else if (actor==player1 && !isteam(actor->team, victim->team)) { player1->kills++; }
+
                 if(actor!=player1 && (!cmode || !cmode->hidefrags()))
                 {
                     defformatstring(ds)("@%d", actor->frags);
diff --git a/src/fpsgame/fps.cpp b/src/fpsgame/fps.cpp
index 5f82fe0..bbbfbbd 100644
--- a/src/fpsgame/fps.cpp
+++ b/src/fpsgame/fps.cpp
@@ -521,6 +521,8 @@ namespace game
             fpsent *d = players[i];
             d->frags = 0;
             d->deaths = 0;
+            d->teamkills = 0;
+            d->kills = 0;
             d->totaldamage = 0;
             d->totalshots = 0;
             d->maxhealth = 100;
diff --git a/src/fpsgame/game.h b/src/fpsgame/game.h
index f186418..a3e9bc6 100644
--- a/src/fpsgame/game.h
+++ b/src/fpsgame/game.h
@@ -465,7 +465,7 @@ struct fpsent : dynent, fpsstate
     int lasttaunt;
     int lastpickup, lastpickupmillis, lastbase, lastrepammo, flagpickup;
     int superdamage;
-    int frags, deaths, totaldamage, totalshots;
+    int frags, deaths, kills, teamkills, totaldamage, totalshots;
     editinfo *edit;
     float deltayaw, deltapitch, newyaw, newpitch;
     int smoothmillis;
@@ -477,7 +477,7 @@ struct fpsent : dynent, fpsstate

     vec muzzle;

-    fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), deaths(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), muzzle(-1, -1, -1)
+    fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), deaths(0), kills(0), teamkills(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), muzzle(-1, -1, -1)
     {
         name[0] = team[0] = info[0] = 0;
         respawn();
diff --git a/src/fpsgame/scoreboard.cpp b/src/fpsgame/scoreboard.cpp
index 3580b20..82c4aea 100644
--- a/src/fpsgame/scoreboard.cpp
+++ b/src/fpsgame/scoreboard.cpp
@@ -316,6 +316,14 @@ namespace game
                 }
             }
         }
+
+        g.textf("your stats", 0xFFFF80, "server");
+        g.pushlist();
+        g.textf("score: %d ", 0xFFFFDD, NULL, player1->frags);
+        g.textf("kills: %d ", 0xFFFFDD, NULL, player1->kills);
+        g.textf("deaths: %d ", 0xFFFFDD, NULL, player1->deaths);
+        g.textf("teamkills: %d", 0xFFFFDD, NULL, player1->teamkills);
+        g.poplist();
     }

     struct scoreboardgui : g3d_callback
Posted in howto, software | Leave a comment

NoSQL v. SQL is the worst holy war ever.

This seems to be filled with religious contention, as demonstrated at http://news.ycombinator.com/item?id=1163039 . Both sides are talking past each other, so I want to lay it out flat.

First of all, while NoSQL and RDBMS can sometimes exclude one another, they should not be seen as adversaries. NoSQL is designed to address a certain problem space and RDBMS is designed to address another. Both can be an important part of one infrastructure. So all of the resentment between sides is pointless.

Relational databases scale. NoSQL databases scale. Both are scalable and tunable, depending on the situation. Sometimes an RDBMS will be better for your project (yes, even in performance). Sometimes a NoSQL datastore will be better for your project.

NoSQL datastores like CouchDB and MongoDB are developed by competent developers. They are used by competent developers.

Relational and SQL-bearing databases like SQL Server and PostgreSQL are developed by competent developers. They are used by competent developers.

NoSQL offers a barebones solution for people whose primary concerns are speed and load. RDBMS offer a full-fledged solution for people whose primary concerns are data integrity and interrelatibility.

There might be a place in your organization for both!

There is no need to get haughty about this. Pick the design that works best for your problem set. There is no need for one to eliminate the other. Both are useful.

Good software development is all about good judgement. Anyone can learn syntax rules and throw together something that kind-of-sort-of works, but a good developer will know when to deploy one thing and when to deploy another. Keep your options open and stop the silliness.

NoSQL v. SQL is the worst holy war ever.

Posted in programming, whining | 15 Comments

python-ldap “expected a string in the list”

This error is given by python-ldap on Python 2.x on certain operations when it receives unicode objects where it expects a str object. Make sure any strings you pass into python-ldap are string type, not unicode type, and this problem will go away.  :)

Posted in howto, programming | Leave a comment

Mozilla needs to step it up

I’m currently using the Chromium developer builds for Linux and it’s amazing how Chromium is still so much faster than Firefox even though Google Chrome has been out for over a year now and Mozilla just performed a major release this summer.

It’s pretty obvious that TraceMonkey in its present state doesn’t hold up to either V8 or SquirrelFish Extreme (which score rather similarly in my experience, usually with SFX a relatively slight margin ahead of V8). I understand that TraceMonkey is much more competitive on Windows, but I almost never use Windows so I don’t care to look into that.

Mozilla really needs to focus on getting consistently good performance if they want to remain relevant.

Chromium is a godsend because of the competition and development it has both encouraged and provided in regard to in-browser JavaScript VMs. It is crucial to the future of the web that we get this show on the road, because fast JavaScript and HTML 5 canvas means the end of proprietary, patent-encumbered necessary evils like Flash and Silverlight. It’s almost impossible to browse without Flash anymore, and that must change.

I’m annoyed at Mozilla because despite their overtures and aggrandizing, Firefox is improving very slowly, and still can’t seem to cope with many of the same demos that Chrome 1.0 was chewing through without issue.

The sad thing is that I don’t really want to switch to Chromium and I don’t want the world to switch to it either. Google has way too much control as it is, with access to almost everyone’s email, search history, etc., and the ability to effectively kill off anyone who depends on referrals from search traffic (most sites see 80%-90% of external search referrals from Google) and Firefox already has thousands of good extensions and themes, not to mention a slight rapport and installed base in the general public.

But Chromium is just so much faster and safer; even if I could bring myself to ignore the 250% speed difference in _just_ the JavaScript VM (no mention here of Chromium’s vastly faster user interface), Firefox has been crashing a lot lately due to erroroneous packaging by my distro, but if and when Chromium crashes, it only brings down the affected tab (every tab is its own process in Chromium) and everything else remains intact, which, at least this week, has made browsing much more pleasant.

Chromium’s every-tab-as-a-process technique also makes exploits much more difficult.

These are the results I just got from Sunspider, against the latest available Chromium and Firefox 3.7 nightly builds on an up-to-date Arch Linux install with kernel 2.6.31.

This is a 32-bit Chromium against a 64-bit Firefox, but the 32-bit to 32-bit results were similar and actually a bit less favorable to Firefox.

TEST                   COMPARISON            FROM                 TO             DETAILS

=============================================================================

** TOTAL **:           2.22x as fast     1092.2ms +/- 4.7%   492.6ms +/- 3.6%     significant

=============================================================================

  3d:                  2.10x as fast      154.4ms +/- 1.5%    73.4ms +/- 4.3%     significant
    cube:              1.87x as fast       47.2ms +/- 6.0%    25.2ms +/- 5.4%     significant
    morph:             1.40x as fast       35.0ms +/- 0.0%    25.0ms +/- 7.0%     significant
    raytrace:          3.11x as fast       72.2ms +/- 2.8%    23.2ms +/- 5.9%     significant

  access:              3.50x as fast      130.8ms +/- 1.6%    37.4ms +/- 6.5%     significant
    binary-trees:      20.0x as fast       40.0ms +/- 3.1%     2.0ms +/- 44.0%     significant
    fannkuch:          4.00x as fast       55.2ms +/- 1.9%    13.8ms +/- 9.9%     significant
    nbody:             1.28x as fast       23.6ms +/- 2.9%    18.4ms +/- 3.7%     significant
    nsieve:            3.75x as fast       12.0ms +/- 12.7%     3.2ms +/- 17.4%     significant

  bitops:              ??                  36.6ms +/- 6.2%    37.0ms +/- 4.1%     not conclusive: might be *1.01x as slow*
    3bit-bits-in-byte: ??                   1.6ms +/- 42.6%     2.4ms +/- 28.4%     not conclusive: might be *1.50x as slow*
    bits-in-byte:      1.18x as fast       10.6ms +/- 6.4%     9.0ms +/- 9.8%     significant
    bitwise-and:       *4.27x as slow*      2.2ms +/- 25.3%     9.4ms +/- 7.2%     significant
    nsieve-bits:       1.37x as fast       22.2ms +/- 8.3%    16.2ms +/- 6.4%     significant

  controlflow:         10.7x as fast       34.4ms +/- 4.1%     3.2ms +/- 17.4%     significant
    recursive:         10.7x as fast       34.4ms +/- 4.1%     3.2ms +/- 17.4%     significant

  crypto:              1.82x as fast       56.8ms +/- 7.0%    31.2ms +/- 6.5%     significant
    aes:               3.57x as fast       33.6ms +/- 8.1%     9.4ms +/- 7.2%     significant
    md5:               1.29x as fast       14.2ms +/- 3.9%    11.0ms +/- 8.0%     significant
    sha1:              *1.20x as slow*      9.0ms +/- 16.9%    10.8ms +/- 9.6%     significant

  date:                2.28x as fast      171.6ms +/- 2.2%    75.2ms +/- 3.9%     significant
    format-tofte:      3.46x as fast      104.4ms +/- 3.4%    30.2ms +/- 1.8%     significant
    format-xparb:      1.49x as fast       67.2ms +/- 2.4%    45.0ms +/- 5.9%     significant

  math:                *1.05x as slow*     45.4ms +/- 2.4%    47.6ms +/- 3.5%     significant
    cordic:            1.06x as fast       20.2ms +/- 2.8%    19.0ms +/- 6.5%     significant
    partial-sums:      *1.10x as slow*     18.8ms +/- 3.0%    20.6ms +/- 3.3%     significant
    spectral-norm:     *1.25x as slow*      6.4ms +/- 17.4%     8.0ms +/- 0.0%     significant

  regexp:              4.44x as fast       78.2ms +/- 12.2%    17.6ms +/- 3.9%     significant
    dna:               4.44x as fast       78.2ms +/- 12.2%    17.6ms +/- 3.9%     significant

  string:              2.26x as fast      384.0ms +/- 11.2%   170.0ms +/- 4.8%     significant
    base64:            *1.60x as slow*     11.0ms +/- 8.0%    17.6ms +/- 6.3%     significant
    fasta:             2.49x as fast       72.8ms +/- 3.9%    29.2ms +/- 7.6%     significant
    tagcloud:          2.83x as fast      102.4ms +/- 6.7%    36.2ms +/- 7.4%     significant
    unpack-code:       3.02x as fast      162.6ms +/- 17.7%    53.8ms +/- 3.4%     significant
    validate-input:    -                   35.2ms +/- 18.3%    33.2ms +/- 4.9%
Posted in software, whining | Leave a comment

Removing Adobe Drive CS4 in Windows

So, after sitting around for more than an hour waiting for Adobe’s indecently bloated CS4 installer to finish installing Photoshop and Flash, I right-click on a file, and am rewarded with a lovely little “Adobe Drive CS4″ context option. I definitely didn’t want this, and I’m upset that when all I asked for was Flash and Photoshop two new Adobe submenus appear on my Start list, one containing only “Adobe Media Player” and another containing nine items, only two of which I asked for, plus another top-level icon for “Acrobat.com”, so Adobe sucks.

Anyway, it seems that the recommended method to remove Adobe Drive CS4 from the context menu is to open the installer and uninstall it (funny that I wasn’t asked about this the first time), but if you’re running Windows in a virtualized guest like me and don’t want to wait the ten minutes it takes Adobe to “[check your system profile]” and “[Load] Setup”, remove these two registry keys:

HKEY_CLASSES_ROOT\AllFilesystemObjects\shellex\ContextMenuHandlers\{C95FFEAE-A32E-4122-A5C4-49B5BFB69795}
HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\{C95FFEAE-A32E-4122-A5C4-49B5BFB69795}

and you should be freed from offending entry.

Alas, Adobe Drive CS4 is still sitting around somewhere sucking up space uselessly, but we’ll leave well enough alone for now.

Posted in howto, whining | Leave a comment

Joel’s “Duct-Tape Programmer” is the only programmer you should ever hire.

I’ve just finished reading Joel Spolsky’s “Duct Tape Programmers” and jwz’s response to it.

These posts strike a chord with me, especially that Spolsky spends the entirety of the article praising “The Duct-Tape Programmer” before he urges you not to try it. Mr. Spolsky should consider this situation:

I’ve just got off a job where the on-staff programmers were absolutely adamant that CakePHP be deployed in _every_ conceivable usage. The manager was brand-new, fresh out of college, with no mentionable experience. The other developer was a contracted freelancer who has never been exposed to any “decent” work (unless you count his own, which, of course, he does).

Neither one of these people know about Joel Spolsky, Jamie Zawinsky, Aaron Seigo, or almost any other important software commentator or developer, and they make very few strides toward self-improvement.

When I left this team, they were weeks behind schedule because the naive and helpless manager/developer was unable to match his task and the contracted developer’s blinding arrogance and selfish motives regularly incited rewrites (of everyone’s code, never just his own), and caused the whole system to run completely amok. What they’ve completed is horrendously slow and unintuitive.

Mr. Spolsky, when you implore your readers not to follow in jwz’s footsteps of judgment and application, is this what you envision? Because this is where it leads. Obsession with fads or hyperfocus on one area of good practice and other symptoms of programming elitism do no good to someone actually interested in developing or maintaining functional software. Both employees in the above scenario had often-prattled lines to back up their incompetence (“premature optimization”, which I, regrettably, taught them, was their favorite), but the fact is that the principles and strategies these things represent are no good without context.

No one should ever hire someone who’s not a “duct-tape programmer” as Joel defines it, because they’re not actually “duct-tape programmers”, they’re the only the competent players in the field. Good programming is all about good judgment.

Computers are fast these days, and can take a lot of crappy programming, but unnecessarily wasteful solutions do tend to add up to a noticeable detriment in any sizable application. Sometimes this is a valid tradeoff, but sometimes it isn’t; good programming is all about finding the right balance.

I can’t tell you how many hours the contracted programmer wasted debugging functions deep within the netherparts of CakePHP when a faster, better, and more suitable custom component could have been built much faster and maintained much easier. That’s an example of a bad programmer because no matter how well he knows the target platform, he’s going to regularly misapply that knowledge.

Spolsky’s description paints the duct-tape programmer as an ignoramus, a programmer who’d just as well stick to pre-1990 languages, methods, and conventions, but that’s clearly not the case with jwz, who was one of the first third-party developers for the Palm Pre. jwz, like all other good programmers, simply knows how and when to avoid cruft and how and when to leverage existing work.

So, when Joel says the “duct-tape programmer”, what he really means is the “pragmatic, profitable programmer, the only kind of programmer you should ever hire or use; a ‘good’ programmer”. These programmers do follow the changes in the field and they do play with new technologies and methods. They simply know when to experiment, when to complicate, when to simplify, and when to ship.

There’s not necessarily anything wrong with C++, Java, Flash, or any of the thousands of other tools out there, most of which were developed for a Good Reason(tm); you just have to have the judgment to know when, where, and how to deploy them such that the product will perform adequately and business needs will be met.

Do yourself a favor and pattern your next hire after jwz; get a programmer with the know-how and the wisdom, because one is useless without the other.

Posted in business, programming | Leave a comment

Inaugural Post

Blog opening now. I’m doing this so that I can expound on opinions in a general, linkable sense, instead of just as comments on reddit or HN or the other communities I patronize. There’s nothing wrong with linking to a reddit thread, and I’m happy to do that when it’s relevant, but this is a mechanism for me to write in generalized formats instead of specific replies (which also allows me to hone writing skills in a way I haven’t exercised for a long time), to be able to provide links to these crystalized renditions where relevant, and to get a more official outlet.

This site is being operated on Deseret Technology’s servers and will contain programming and business related material, but also probably political, philosophical, ideological, personal, and religious material. I recognize this may alienate some prospective clients, but I’m willing to try it and see where it goes. I don’t really want intolerant or closed-minded clients, because attitudes of closed-mindedness, intolerance, jingoism, etc. infect areas that branch into our work, and we don’t want to deal with those attitudes where avoidable. We can have a differing opinion, especially on something irrelevant to programming, and still provide great work on congenial terms.

This is a standard wordpress installation. No -mu here for now. I may invite others to contribute  as occasion suggests, but for now, it’s just me. : )

Posted in general | Leave a comment