Author Archive

Crappy Job Ads on craigslist

Friday, January 18th, 2008

Opinions on how we should and shouldn’t compose our resumes are a dime a dozen in the blogosphere. Well, in fact they’re free, though some may be worth a little more. The topic is an old one, and though the Internet and modern practices (like using craigslist or monster) may have brought new rules into play, it’s still about making yourself look smart, experienced, and sane.

The flip side of resume writing is the art of advertising open positions when seeking to hire people. I can’t keep track of whether we’re in a “buyer” or “seller” market in the software development world, but it’s clearly true that individual companies in individual markets frequently find themselves fairly desperate to hire developers. My own experience is that it takes quite a while to find candidates, and even longer to hit upon a good one.

Thus it seems to me that writing good copy for craigslist “help wanted” adds would be something employers do as a matter of course. Sadly, that’s not the case. They’re generally:

  • ugly;
  • rife with spelling and grammar errors;
  • composed of weird or stilted language;
  • jammed with buzzwords and product/technology names.

I know that some of the problems stem from the route the ads take from the hiring manager through the HR group (and possibly through the recruiters), but that’s hardly an excuse. The end result is that I read the ads, you read the ads, and we form opinions about the personality and culture of the organization. I caught myself the other day rolling through craigslist ads, one after the other, shaking my head after almost every single one. Ad after ad leaves me with impressions of people in cheap suits, dingy offices, and wildly disorganized (or just crazy) product development environments. You know what I’m talking about: little businesses where the guy in charge tells you that lots of the work was done by “the smartest guy I know, he’s a wiz”. Dreary failure is the vague mental picture I form.

What’s going on? Is it really the case that most businesses trolling craigslist are seedy or dysfunctional? I know that the ads are dirt cheap (free here), but the page view rate is so high that even businesses with money to blow on recruiters would be foolish not to use the service when they’re in need. (The place I work now has used craigslist with no success; I never looked at our ads.)

Indulge my laughable fantasy that somebody in a position to be influenced by my advice might read these words: take care with your craigslist ads. Think about them carefully, about the tone, the language, and the image they create. Correct the misspellings and grammar errors. Clean up the random capitalization of Important Words, and NOTHING SHOULD BE ALL-CAPS. Get somebody who actually knows what the buzzwords mean to review the way you’ve piled them on top of each other, and think about whether the things you insist are essential skills are really essential. (Did your top developers on your key products have all those skills back a year or two ago?)

Steve Yegge wrote about “weasel words” in resumes. In my opinion there’s a parallel species of words that crop up in job ads. I’m talking about stuff like “dynamic work environment”. What does that mean? “Should be an excellent team player.” Again, what does that mean? Who do they expect to screen out with that? I don’t want to hear about your corporate “energy”; it’s vaguely creepy and I’ll get the real story (or close to it) in an interview anyway. Just be clear and friendly, and describe the work.

HTML Escaping in Javascript

Saturday, December 29th, 2007

The Protoype library augments the native “String” class with an “escapeHTML” method. It’s handy for scrubbing user-supplied text onto the page:

  $('someSpan').update(randomString.escapeHTML()); 

I found recently that all that’s “escaped” by the function are the characters ‘&’, ‘<‘, and ‘>’. I found that out the hard way when I had assumed it’d also escape single- and double-quote characters. (Why did I assume that? I’m dumb maybe, but I figure it’s nice for building HTML attribute values. Whatever.)

The implementation of “escapeHTML” (on Firefox, at least, and maybe Opera) is pretty odd, and clearly something done for performance. What the library does is to create a div element with a text node in it, and keep that around. A call to the “escapeHTML” function is handled by setting the “data” attribute of the text node to the string being escaped. The return value is then the “innerHTML” property of the div. Thus the function leverages the internals of “innerHTML” and has the translation done in the (presumably) fast compiled innards of the browser. Here’s a rendition of what it looks like; it’s not exactly like this but this is (I think) equivalent:


  escapeHTML: (function() {
    var rv = function(s) {
      var self = arguments.callee;
      self.text.data = s;
      return self.div.innerHTML;
    };
    rv.div = document.createElement('div');
    rv.text = document.createTextNode('');
    rv.div.appendChild(rv.text);
    return rv;
  })()

The simple-minded version used for WebKit and IE looks like this:


  escapeHTML: function(s) {
    return s
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;');
  }

Whether or not I’m right in thinking that the library’s “escapeHTML” function should deal with quotes, I need something that does. Clearly I can’t leverage the “innerHTML” trick, because the browser apparently disagrees with me about quotes. I could clearly just use an extended version of the repeated-“replace” version. There’s another way, however:


  escapeHTML: (function() {
     var MAP = {
       '&': '&amp;',
       '<': '&lt;',
       '>': '&gt;',
       '"': '&#34;',
       "'": '&#39;'
     };
      var repl = function(c) { return MAP[c]; };
      return function(s) {
        return s.replace(/[&<>'"]/g, repl);
      };
  })()

The “replace” function (native to Javascript “String” objects) can take a function as its second argument. The function is passed the results of each match. Thus this version above matches on any of the characters I want to escape, and then translates them to the HTML entities via a little map object. It seems like this would be better in the case of “clean” strings, because the pattern would match nothing and so the string would be returned unchanged.

In order to see what the performance realities were, I started hacking up a little test page. After a while, I got tired of editing and re-editing to see how different tinkerings with the different function versions would affect the timing. What I wanted was a setup to make a little table: different test datasets (short strings, long strings, clean strings, dirty strings) across the top, and the different “escapeHTML” versions at the left. The cells would be the average time of a pass over each string in each test list. Because I’m silly I wanted the table to be filled in as the tests ran, so the numbers would show up while I stared at the screen.

To do the little incremental animation thing made my head hurt for a while. I took a break to cook some muffins (orange cranberry – here’s a tip: when making orange muffins or any sort of orange quick bread, use frozen concentrated orange juice instead of plain juice, and a teeny bit of orange oil) and while I was filling up the muffin cups I had an idea. I think it’s something that people who’ve been using functional languages would probably think of as being perfectly obvious.

Prototype has an “inject” routine, which is like “foldl” in … well, in something; Scheme maybe? I know that in the Erlang “lists” module it’s “lists:foldl”. The function is a method available on any Enumerable object, like an array. It takes two arguments (well, three, but ignore that for now), the first being an initial value and the second being an iterator function. The “inject” mechanism passes the initial value and the first element of the collection to the function. The function does something, and returns a value. That’s passed on in the next iteration, with the second element of the list, and so on. The final return value of “inject” is whatever the last invocation of the iterator returns.

Common pedagogical examples of “inject” do stuff like compute an arithmetic reduction over a list of numbers, or build up an array from a function that interprets values in the source array. In my case, what I wanted was a function, one that I could call to start the sequence of test runs. In other words, I needed to have something that would iterate accross the cells of my table, running the “escapeHTML” versions on each list of test strings.

My muffin epiphany was that I could use nested “inject” loops backwards through the table to build up a function that would run the test for its cell, and then invoke the function from the previous cell. (That’s why I’d go backwards through the array – the last function to run would have to be the first function I built.) Thus the “inject” process would build up a chain of functions wrapped around eachother like Russian nesting dolls.

That ended up as a somewhat general-purpose facility that will take a list of functions (with names) and a list of test datasets (with names), and create a table in a selected container, and then fill in the table test by test:


function timings(container, datasets, functions, repeats) {
  // first make the empty table, with headings and left-side labels
  $(container).update(
    "<table><tr><th></th>#{headings}</tr>#{rows}</table>".interpolate({
      headings: datasets.collect(function(sl) {
        return "<th>#{name}</th>".interpolate(sl);
      }).join(''),
      rows: functions.collect(function(fp, rowNum) {
        return "<tr><td>#{name}</td>#{timings}</tr>".interpolate({
          name: fp.name,
          timings: datasets.collect(function(x, colNum) {
            return "<td id='#{r}_#{c}'></td>".interpolate({r: rowNum, c: colNum});
           }).join('')
        });
      }).join('')
    })
  );
  // now make the nested series of functions, and call the one that pops
  // out the top
  functions.reverse(false).inject(null, function(ff, fl, rowNum) {
    return datasets.reverse(false).inject(ff, function(ff, sl, colNum) {
      var tdid = "#{r}_#{c}".interpolate({
        r: functions.length - rowNum - 1,
        c: datasets.length - colNum - 1
      });
      return function() {
        $(tdid).addClassName('pending');
        setTimeout(function() {
          // average the time for some runs over this test dataset
          var avgTime = $R(1, (repeats || 10)).inject(0, function(avg, n) {
            var start = new Date().getTime();
            sl.list.each(fl.fn);
            return (avg * (n - 1) + (new Date().getTime() - start)) / n;
          });
          $(tdid).update(
            (Math.floor(avgTime * 100) + '').replace(/(\d\d)$/, '.$1')
          ).removeClassName('pending');
          // call the next function in the chain - this is the one passed
          // in as the first argument by the "inject" mechanism
          ff && ff();
        }, 250);
      };
    });
  })();
}

Note that the per-cell functions operate via timeout. That’s so that the browser has a chance to catch its breath and update the display between test runs. (The 250ms time was just a random guess, but short times like 10ms were too short). You can see the results of my fooling around here. What I found was kind-of interesting.

First, the “weird” way that Prototype does the escaping (via the “innerHTML” trick) is pretty consistent in performance. It’s slower than the “fun” approach (the single regex with a replace function) when strings are clean, I guess because the browser regex code is pretty well optimized, and the pattern is simple. All of the regex routines get slow on larger strings that require scrubbing. The “hybrid” code on that test page is the “innerHTML” trick with a pre-check via regex.

The “Weird 2” function, which is always slower than “Weird”, is the Prototype “innerHTML” version implemented as in the actual library. Specifically, the div and text node are attached as attributes to the function object itself, and then accessed via “arguments.callee”. In my version (“Weird”), I just used a closure for the elements. Why would the closure be faster?

Oh, and the “multi” ones are the muliple-replace routines.

For my purposes, I’m pretty sure most of the strings that my pages escape are clean. Thus I think I’ll introduce the single-regex version somehow in my world.

Finally, while typing this in, I needed a place to escape the code samples. I think I wrote a C program to do that once a long time ago, but I couldn’t find it. Thus I typed in this page to do it. Maybe people with fancy IDEs have built-in tools for that.

The dark side of {{ }}

Saturday, December 22nd, 2007

Despite having typed in an enormous amount of Java code over the past seven or eight years, my “discovery” of


return new Foo() {{
  setThingy(whatever);
}};

was embarrassingly recent. Because it lets me work more with values than with statements, I like it a lot, and I try to think in terms of using it.

For those still unaware of this surprisingly old feature of the language, it’s possible in general to add anonymous blocks to class definitions. Everybody knows about


static { foo = new BigFoo(); }

Without the static keyword, the block is treated as an appendage to the constructor code. (I guess they run in declaration order, but I don’t care about that at the moment.) Thus the notation

new T() {{ code; }}

means to construct an anonymous subclass of T with some random code that runs along with the no-args constructor for T. (Of course you can also do that when the constructor does have arguments.)

The dark side of that trick is probably obvious to everybody except me, because the dark side has crept in and wasted a lot of my time recently. The code that you type into that {{ }} block is of course code that’s treated as being in the lexical context of the subclass, not that of your surrounding code. Durr. If the initialization statements refer to method names or variable names that are visible in the base class, then the statements are interpreted as being in those terms. That’s really nice when you’re using this to populate a HashMap


return new HashMap() {{
  for (DungHeap dh : allHeaps()) put(dh.getName(), dh);
}};

However, if the base class you’re subclassing has some protected member variables, watch out! The final variables in the surrounding code you’re referencing as part of the initialization will be shadowed. Same goes for utility methods you’d like to call.

This got me just today with a context variable called “headers”. I was initializing a new MimeMessage instance. Guess what’s a protected member variable of a MimeMessage instance?

I still like that notation, for now at least.

Just what is this Javascript object you handed me?

Saturday, December 8th, 2007

Modern Javascript “frameworks” like Prototype, jQuery, and Dojo compete to provide flexible, expressive tools, which is a great thing for Javascript developers. It’s truly astounding how effective these relatively simple and concise tools can be.

One of the challenges faced by toolkit designers stems from the malleability of the Javascript environment – the same malleability that makes the tools possible in the first place. In type-happy (I could have written “stodgy”) languages like Java, the question, “what is this thing?” that code behind an API might ask is always easy to answer; in fact as a Java programmer you don’t really ask the question much unless you’ve done things pretty badly. In Javascript, however, there’s never a good answer. Well, there is – the thing is an Object – but it doesn’t do you much good.

So anyway, coding away the other day I came across an interesting bug, one that turns out to be shared by Prototype, jQuery, and Dojo (and maybe others). It was a case of the toolkit code doing something to check to see if a thing passed through an API was of a particular type so that some work could be done with it. In this case, the toolkit code (Prototype) needed to know whether a value was an Array, because if so then something different had to be done than if the value were a simple scalar. Instead of approaching that situation with a pragmatic, dynamic “duck typing” technique, the code took an approach that a Java programmer would recognize.

Specifically the fault was in code that transformed a “Hash” object into an HTTP query string. The client code has a property list of parameter names and values, which is to be used in a GET URL or an XmlHTTPRequest. The Prototype service has to deal with the fact that a single parameter name may be associated with a list of values. (Recall that an HTML form can have more than one input field with the same name.) The Prototype convention here is that the “toQueryString” routine looks for parameters in the Hash object whose values are arrays:


  // this is 1.5.1 code - it's different in 1.6
  // but the problem remains (for now)
  toQueryString: function(obj) {
    var parts = [];
    parts.add = arguments.callee.addPair;

    this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;
      var value = pair.value;

      if (value && typeof value == 'object') {
        if (value.constructor == Array) value.each(function(value) {
          parts.add(pair.key, value);
        });
        return;
      }
      parts.add(pair.key, value);
    });

    return parts.join('&');
  },
  // ...

(The “addPair” routine that’s hooked up to the return-value array “parts” just builds a “name=value” string with appropriate URL encoding.) See how the code works? There in the loop code where it handles each key/value pair in the Hash object, it checks each value to see if it’s type is “object”. (The Javascript “typeof” is pretty lame.) If it’s an object, then a further test is made to see if the value is an array. That test compares the “constructor” attribute of the value object to the global Array function.

What’s the problem with this? The code is doing something that seems reasonable: if the constructor of the object is the Array function, then it’s an array, right? Sure, this is Javascript, so if the client code has done something stupid like reassign the “constructor” attribute or even reassign the global variable name “Array”, it’ll break, but that would be my fault. Setting that aside, what could possibly go wrong?

First I’ll be philosophical: does that code really need to know for sure that the value was constructed by the Array function? All it really does when it determines that the value is an array is take advantage of the “each” function it expects to find there. I think that a pure (funny word in this case) duck-typing approach would be to check to see if the value object has an attribute called “each” that references a function.

Now on to the practical issue here, the reason that the code is buggy as written. The subtle assumption made in the code is that every array object will have been constructed by the function pointed to by the global variable “Array”. Conversely, it assumes that any object not constructed by the function pointed to by the global variable “Array” must not be a real array. OK then, outside of shenanigans that break things on purpose (reassigning “Array”), how is that assumption problematic?

Well I’ll tell you. A web application can be spread across multiple separate windows. The window objects are linked together into a single DOM graph. Code can “see” up and down the graph into other windows, and functions can be called across window boundaries. In particular, an array can be passed from code on one page into a function on another. The kicker is that every page has its own global context (which means that the term “global” is sort-of questionable), and that includes a “global” variable called “Array.” Oops.

Javascript is not Java. You can’t really put much stock in anything your code might find out about a mysterious parameter, so why compound the problem by asking indirect questions? Just because an object was not apparently constructed by the function you think has to be the one and only “right” one doesn’t mean it won’t work just fine.

This page is a simple example of the problem. Prototype will be fixed soon thanks to the attentions of world-famous Prototype contributor “savetheclocktower.” Dojo and jQuery have similar issues but I haven’t reported them yet. Specifically, jQuery uses the “foo.constructor == Array” deal all over the place. Dojo seems to use “instanceof Array”, which suffers from exactly the same problem. I don’t think that expecting the libraries to work properly on values passed across page boundaries is unreasonable.

Amazon Ring Flash

Saturday, November 10th, 2007

OK so here’s the home-made ring flash. Ingredients:

  • One small Amazon book box
  • 2 Quantaray slave strobes
  • 2 plastic strap ties
  • 1 rubber band
  • 1 piece of random white-ish cotton cloth
  • Aluminum foil
  • Duct tape

(Credit to Pat for most of the assembly photos.)

Holes are cut in the back of the box, one in the middle for the lens and then two on each side for the strobes:

The strobes fit on the back such that the flashy part kind-of pokes into the holes. Plastic strap things hold them in place:

On the front is some cloth. It’s got a frilly pattern woven into it, but I don’t think that’s important:

The lens pokes through the back, and the box fits more-or-less snugly over the filter:

The lens hood is screwed on (yes, screwed) and a rubber band holds the cloth flaps:

Here you can see the catchlight from the contraption:

That’s all there is to it. I can shoot at 1/160, f10 to f16, depending on how close I am. That gives more depth of field than I’ve gotten with daylight. Gallery from this afternoon, immediately following the (re-)assembly of the ring flash:







(That’s a “Batfaced Cuphea” flower; I didn’t notice the aphids until I saw it on the screen.)

For Melissa, tourmaline with amethyst:

Wulfenite:

Dioptase (I think; might be diopside but the crystals seem too big):

Galena (perhaps with sphalerite but I don’t know):

Big Bugs

Friday, November 9th, 2007

Actually just the pictures are big.



These were taken with the Sigma 105 and a home-made “ring flash.” The flash consists of an Amazon book box with the flaps cut off. Through the back (well, the bottom of the box), two holes were cut so that the flash “windows” of two Quantaray cheap-o slave flash units can poke through. The flash units were strap clamped to the box. There’s a round hole in the middle of the box that just fits over the end of the lens (actually it’s over the UV filter). The lens hood holds it in place, sort-of. Then there’s a piece of thin cotton fabric duct-taped over the front (top) of the box, and through a hole in the middle of it pokes the lens hood. Maybe I should take a picture of it.



I don’t know what either of those two things are, exactly. I’ve seen that species of dragonfly a couple of times however, and I have another good picture I got with the Olympus 50mm lens.

Sigma 105mm EX DG macro

Friday, October 26th, 2007




The UPS man delivered my new Sigma 105mm macro lens this afternoon, and I immediately set up a simple facility to try it out. I put an old Weston light meter down on a counter, and next to it I arranged a cheap Quantaray slave and my old Oly T32 on an optical slave hot shoe around it, both pointed up at the ceiling. I set the E-500 flash to 1/64th power and held the camera by hand.



For the coin, I set up a tripod and focused (manually) as close as I could get. The camera was not directly over the coin so it’s not in focus all the way across; I need to rig up a “ring box” so that I can do real close-up planar macro shots.

Danaus plexippus

Sunday, October 21st, 2007

Plant some milkweed, and you’ll get some monarchs.

Caterpillar photo

Several caterpillars hatched out pretty late in the year, almost certainly past the time at which they should have left for Mexico. There’s plenty to eat here however so maybe they won’t mind.

Chrysallis photo

The kids found this chrysallis on the fence, quite some distance from where any milkweed is planted.

Butterfly photo

Two adults, including this big one, were all over the garden this afternoon.

Goose Island State Park

Sunday, October 7th, 2007

Picture of "Big Tree"

That’s “Big Tree”, a big tree at Goose Island State Park in Lamar, TX. Supposedly it’s the biggest live oak tree in the state. It’s not hard to believe, though it’s the kind of thing that weird small towns in Texas concoct all the time. And Lamar, TX definitely counts as one of those.

The picture is all foggy because the camera had just emerged from the air-conditioned van into the intense humidity there, just a couple hundred yards from the giant bathtub that’s the Gulf of Mexico. The landscape around Big Tree is pretty surreal, and I’m told the tree is strongly reminiscent of the “Whomping Willow” from the Harry Potter books. In fact all of Lamar (which is not to describe a very large area of course) seems to be in the grip of a live oak plague.

Picture of sunflowers The state park includes a little spit of land projecting out into Aransas Bay. Dead shellfish and plant material tend to wash up along part of the beach there, so the same creative fire that named the tree has branded that area “Stinky Beach.” It’s actually very pretty in an odd way.

Make My Sandwich Properly!

Saturday, September 8th, 2007

I frequently dine at North By Northwest in Austin. (Yes I’m naming names here people.) Mostly the food is good, but I swear that place annoys me with their propensity to create obviously inferior dishes that could have been fine, and should have been were there anyone paying attention. I’m not talking about improperly cooked instances of a generally good dish: I’m talking about recipes that are just plain bad, for no good reason.

Case in point: the Grilled Portabello Sandwich. First, of course, it’s Portobello. That I can forgive as virtually every grocery store on the planet spells the word incorrectly too. The “sandwich” involves grilled mushroom (sliced), eggplant (sliced thick), sun-dried tomatoes, mozzarella cheese, and some sort of ranch-like dressing, all wrapped in a thick pita-like (but definitely not really a pita) bread.

OK, where to start with what’s wrong. I think I’ll work my way in by pointing out that eggplant is really not something anybody should want on a sandwich. I can possibly imagine eggplant that’s been roasted pretty fiercely – sliced thin – and then topped with cheese, but really the vegetable has little taste. Forget it. Make a nice eggplant-olive salad on the side if somebody really wants to make Big Eggplant happy. If it absolutely must be in the sandwich, cook it. Normal people do not want to eat half-cooked eggplant chunks.

The mushrooms which star in the dish also need to be completely cooked. Completely. What’s more, they need to be seasoned, and this really is one of the main problems with the sandwich that make me wonder whether anybody there ever actually tastes the things. This is a rich sandwich at a brewpub and the lead ingredient in the dish has been given no pizazz at all.

The sun-dried tomatoes are fine, but there’s not enough of that. What the sandwich sorely needs is oomph. What sort of thing do you do to a grilled sandwich in this form to provide oomph? Right: carmelized onions and grilled marinated banana peppers. I want a mushroom cheesesteak, because that’s exactly what this sandwich wants to be! There’s a mushroom cheesesteak locked up with those demented inappropriate chunks of eggplant, and it’s whimpering pitifully for help!

Finally, the cheese: it hits the table, and it’s still cold! That’s right: the barely-grilled vegetables are more-or-less hot, but the cheese is stuffed into the bread cold from the refrigerator. I’m sorry, but a cold lump of mozzarella (unmelted, in other words) is not a value-add. It’s a lump of solid milk.

The ranch dressing is fine, such as it is, but it’d be completely unnecessary were the rest of the dish done properly.

Here’s what needs to happen:

  • Marinate the mushrooms in something like thinned soy sauce, cheap balsamic vinegar, or a dry salt/pepper/thyme rub. Almost anything would be better than nothing.
  • Get the onions and peppers going on the griddle. The onions can be pre-cooked of course.
  • Sautee the mushrooms – sliced – and cook them until they are actually done. I want some browning.
  • Combine into a little pile of veg and top with a handful of shaved provolone and let the cheese melt in a little – on the grill. The whole assembly should be hot.
  • Hit the veg with some parsley (forget the ranch) and plate out onto the warm pita-like stuff (which I confess isn’t bad at all).

I find it really hard to believe that the above sandwich would be less well-received than the weird dish currently served.