House rental, showers, and auctions

July 30th, 2010

I’m currently in the prologue of the house-rental process. Our sights are set on a four-bedroom house with an interesting property: the room resources are of differing value — not in terms of square-footage, but other, less easily scalable factors.

  • One bedroom has an attached bathroom and a slightly larger closet (the master bedroom).
  • One bedroom is on its own floor with a half-bathroom. [*]
  • The other two share a full bathroom, whose shower is also a resource shared with the bedroom mentioned above.

So how do we dole out the resources of unequal value in a manner that everybody considers fair?

(Talk about first-world problems…)

Proposed solutions

Three systems for deciding the room allocations have been proposed, and one has been rejected:

  • Randomly assign choosing priority: this was dismissed because the person with the last priority inevitably feels "stuck with" a room.
  • Entirely random: we take four playing cards from a deck, associate each card with a room, shuffle the cards until everybody is satisfied, then deal each person a card. That’s the room that they get. Everybody is equally "stuck with" a room, and not due to the actions of any other person.
  • Bidding system: the auction would move from perceived-most-valuable-room to perceived-least-valuable-room. Bidding starts with the master bedroom at the evenly-divided rental rate. Once a winner/price is determined for that room, the process is repeated for the room with the half-bathroom, with a newly-divided rental rate. Once a point is reached where nobody is willing to place a bid on a room, the rest are assigned at random. Each person, through their own decision to bid or not to bid, ends up with the room of their choosing.

I’m personally a fan of the simplicity and total lack of competition in the random system, but if the bidding system is more likely to lead to the optimal outcome, it must be considered! (Of course, care must be taken to address possible social ramifications.)

During casual discussion we noted that the bidding system would be strategically interesting. If a person were not really interested in getting a high-value room but didn’t care all that much if they did, it is clearly in their favor to drive bids on the early rooms as high as possible — this would entail a decrease in the payment rate for a later room.

I perused the Wikipedia entry on auction theory and realize that we were assuming an open/ascending bid auction, but a first-price/sealed-bid auction might be less socially stressful. [†] My main fear is that open bidding would get carried away (it’s exciting, after all) and participants would come to regret their bids.

In any case, it’s an interesting problem I thought I would share. Suggestions are welcome; otherwise, I’ll write a follow-up entry as to how it turns out.

Footnotes

[*] This means it has no shower. Stupid terminology, but I suppose it has a nicer ring than "toilet room".
[†] As an aside, the game theory described on that page also seems to discuss provable equilibrium of a single auction, whereas our auctions have dependent equilibrium values.

Coding style as a feature of language design

July 29th, 2010

roc recently posted a thought-provoking entry titled, "Coding Style as a Failure of Language Design", in which he states:

Languages already make rules about syntax that are somewhat arbitrary. Projects imposing additional syntax restrictions indicate that the language did not constrain the syntax enough; if the language syntax was sufficiently constrained, projects would not feel the need to do it. Syntax would be uniform within and across projects, and developers would not need to learn multiple variants of the same language.

I totally agree with roc’s point that there is overhead in learning-and-conforming-to local style guidelines. I also agree that this overhead is unnecessary and that language implementers should find ways to eliminate it; however, I think that imposing additional arbitrary constraints on the syntax is heading in the wrong direction.

Your language’s execution engine [*] already has a method of normalizing crazy styles: it forms an abstract syntax tree. Before the abstract syntax tree (AST) is mutated [†] it is in perfect correspondence with the original source text, modulo the infinite number of possible formatting preferences. This is the necessary set of constraints on the syntax that can actually result in your program being executed as it is written. [‡]

So, why don’t we just lug that thing around instead of the source text itself?

The dream

The feature that languages should offer is a mux/demux service: mux an infinite number of formatting preferences into an AST (via a traditional parser); demux the AST into source text via an AST-decompiler, parameterized by an arbitrarily large set of formatting options. Language implementations could ship with a pair of standalone binaries. Seriously, the reference language implementation should understand its own formatting parameters at least as well as Eclipse does. [§]

Once you have the demux tool, you run it on your AST files as a post-checkout hook in your revision control system for instant style personalization. If the engine accepts the AST directly as input, you would only need to demux the files you planned to work on — if the engine accepted an AST directly as input in lieu of source text, this could even be an optimization.

Different execution engines are likely to use different ASTs, but there should be little problem with composability: checked-in AST goes through standalone demux with an arbitrary set of preferences, then through the alternate compiler’s mux. So long as the engines have the same language grammar for the source text, everybody’s happy, and you don’t have to waste time writing silly AST-to-AST-prime transforms.

In this model, linters are just composable AST observers/transforms that have no ordering dependencies. You could even offer a service for simple grammatical extensions without going so far as language level support. Want a block-end delimiter in the Python code you look at? [¶] Why not, just use a transform to rip it out before it leaves the front-end of the execution engine.

Reality

Of course, the set of languages we know and love has some overlap with the set of languages that totally suck to parse, whether due to preprocessors or context sensitivity or the desire to parse poems, but I would bet good money that there are solutions for such languages. In any case, the symmetric difference between those two sets could get with it, and new languages would be kind to follow suit. It would certainly be an interesting post-FF4 experiment for SpiderMonkey, as we’ve got a plan on file to clean up the parser interfaces for an intriguing ECMAScript strawman proposal anywho.

Footnotes

[*] Interpreter, compiler, translator, whatever.
[†] To do constant folding or what have you.
[‡] Oh yeah, and comments. We would have to keep those around too. They’re easy enough to throw away during the first pass over the AST.
[§] Even more ideal, you’d move all of that formatting and autocompletion code out of IDEs into a language service API.
[¶] Presumably because you despise all that is good and righteous in the world? ;-)

B&B++: bed and breakfast for programmers

July 20th, 2010

1. Collect background

This is the latest in my steal-my-idea-but-give-me-free-stuff-after-you-do series, with slightly more earning potential than my last installment, "Strike a Cord".

I recently spoke to some Mozillians who had participated in a "code retreat" — I’d only heard tale of such a thing in lore and folk song, but it seems like a brilliant concept.

The idea is this: a small think tank (of one or more persons) requires a large amount of code throughput on a task which requires a high degree of focus. To facilitate that, they run far from the middling issues of civilized society and deep into the wilderness [*] to code "butt-necked in harmony with Eywa". [†] Through single-minded concentration and a dearth of non-maskable interrupts, they emerge victorious. [‡]

2. ?

Follow these simple steps to steal my idea:

  1. Assume that the aforementioned code retreat process is awesome.
  2. Make a bed-and-breakfast in the outskirts of a city that’s attractive to programmers (for whatever reason).
  3. Offer retreats with high-speed internet access, offices with whiteboards, mirra chairs, height-adjustable desks, pay-as-you-go phone conference equipment, high-res DLP projectors, disco balls, whatever. Make it clearly "the works". If you want to go even further, mount speakers and sound-proof the walls. [§]
  4. Make the experience as luxurious and classy as reasonably possible so that the programmers respect the "sanctity" of the retreat: chef-prepared meals, an indisputably good coffee machine, a Z80 prominently featured as a piece of wall art, and a complimentary bag-o-munchy-chips regimen. Beautiful scenery in which one can walk and think would definitely be a plus, and proximity to a nerd-friendly bar never hurt a nerdy establishment either.

The patrons have a good degree of flexibility as a result of this setup. They might hole themselves away in offices 95% of the time, emerging only to sleep, gather delicious food, and scuttle back into their offices. Alternatively, if they’re on a more casual endeavor (coding vacation?), they might choose to strike up conversations with people at meals and go out to see the sites.

3. Profit!

Please do steal my idea and make a lot of money for yourself (share it with no one!) — I only ask that you offer me a free stay once you get off the ground.

I’ll leave you off with a little marketing campaign idea:

B&B++: universally evaluated as the way to B, and, after each bed and breakfast, we get a little bit better. Until we overflow. [¶]

Footnotes

[*] Or a hotel.
[†] Sadly, I can’t take credit for this phrase.
[‡] Readers familiar with XP may draw a parallel to the practice of Kanban, which has a fascinating backstory, and acknowledges the awesome power of JIT.
[§] For the mercy of those who dislike techno.
[¶] Hey, I’m giving this advice away for free, you can’t expect it to all be good. No company ever survived giving their excellent primary product away for free. [#]
[#] Ugh, too much meta-humor. If you’ve read and understood up to this point, I apologize.

Tool teams should work like sleeper cells

July 14th, 2010

I’ve had some unique experiences interacting-with and participating-in tool development at previous companies that I’ve worked for, with the quality of those experiences in the broad spectrum from train-wreck to near-satisfactory. From that mental scarring has emerged the weighty goo of an idea, which may be interesting food for thought. [*]

How it starts

At some point in a company’s growth, management notices that there is a lot of sub-par, [†] redundant, and distributed tool development going on. Employees have been manufacturing quick-and-dirty tools in order to perform their jobs more efficiently.

Management then ponders the benefit of centralizing that tool development. It seems like an easy sell:

  • Help ensure ongoing productivity gains — mission-critical tools that stop working or contain heinous bugs are a hidden liability
  • Foster tool developer expertise on a specialized team
  • Eliminate needless repetition by creating shared code bases and consolidating infrastructure resources

Good management will also consider the negative repercussions of turning distributed and independent resources into a shared and centrally managed resource:

  • Everybody wants a slice of the tool pie, because tools make our life better, and there always seems to be some stupid crap to automate.
  • Everybody wants a piece of the compute resources, because more compute makes parallelizable analyses go faster.
  • If you build it, they will come.

How I’ve seen it work (warning: depressing, hyperbolic)

  1. A group at the company makes a strong enough case to the centralized-tool-management machinery — a request for tool development is granted.

  2. A series of inevitably painful meetings are scheduled where the customer dictates their requirements, after which the tool team either rejects them or misunderstands/mis-prioritizes them because: a) that’s not how it works — they have to actively gather the requirements, and b) they don’t have enough time to do all the silly little things that the customer wants.

    Because people are fighting each other to get what they want, everybody forgets that the customers haven’t really described the problem domain in any relevant detail.

  3. The tool team developers are happy to go code in peace, without going back for more painful meetings. They create a tool according to their understanding of the requirements during the first iteration.

  4. The customer has no idea how the tool team came up with a product that was nothing like their expectation. They say something overly dramatic like, “it’s all wrong,” pissing off the tool team, and lose faith in the ability of the tool team to deliver the product they want.

  5. The customer goes back to doing it manually or continue to develop their own tools, expecting that the tool team will fail.

  6. The tool team fails because the customer lost interest in telling them what they actually needed and giving good feedback. It wasn’t the tool that anybody was looking for because the process doomed it from the start.

I say that this scenario is depressing because tool teams exist to make life better for everybody — they enjoy writing software that makes your life easier. Working with a tool team should not be painful. You should want to jump for joy when you start working with them and take them out to beers when you’re finished working with them, because they’re just that good. I think that, by taking a less traditional approach, you will be able to achieve much better results…

How it should work

  1. A group at the company makes a strong enough case to the centralized-tool-management machinery — a request for tool development is granted.
  2. A small handful of tool team operatives [‡], probably around two or three people, split off from the rest of the tool team and are placed in the company hierarchy under the team of the customers. They sit the customers’ cube farm, go to their meetings to listen (but no laptops!), etc., just like a typical team member would.
  3. The customer team brings the operatives up to speed on the automatable task that must be performed each day through immersion. Depending on the frequency, breadth, and duration of the manual processes, the operatives must perform this manual process somewhere on the scale from weeks to months, until they develop a full understanding of the variety of manual processes that must be performed. [§] All operatives should be 100% assigned to the manual tasks for this duration, temporarily offloading members of customer team after their ramp-up.
  4. Bam! With an unquestionably solid understanding of the problem domain, the tool team sleeper cells activate. 80% of the manual task load is transitioned off of the operatives so that they can begin development work. Agile-style iterations of 1-2 weeks should be used.
  5. After each iteration there must be a usable product (by definition of an iteration). As a result of this, a percentage of the manual task load is shifted back onto the operatives each iteration, augmenting the original 20%. If the tool is actually developing properly, the operatives will be able to cope with the increased load over time.
  6. As the feature set begins to stabilize or the manual task load approaches zero (because it has all been automated), the product is released to the customers for feedback and a limited amount of future-proofing is considered for final iterations.
  7. Most customer feedback is ignored, but a small and reasonable subset is acted on. If the operatives were able to make do with the full task load plus development, it’s probably a lot better than it used to be, and the customer is just getting greedy.
  8. The customer takes the operatives out for beers, since the tool team saved them a crapload of time and accounted for all the issues in the problem domain.
  9. A single operative hangs back with the customer for a few more iterations to eyeball maintenance concerns and maybe do a little more future-proofing while the rest head back to the tool team. The one who hangs back gets some kind of special reward for being a team player.

Conclusion

In the sleeper cell approach, the operatives have a clear understanding of what’s important through first hand knowledge and experience and, consequently, know the ways in which the software has to be flexible. It emulates the way that organic tool development is found in the wild, as described in the introductory paragraph, but puts the task of creating the actual tool in the hands of experienced tool developers (our operatives!).

I think it’s also noteworthy that this approach adheres to a reasonable principle: to write a good program to automate a task, you have to know/understand the variety of ways in which you might perform that task by hand, across all the likely variables.

The operatives are forced to live with the fruits of their labor; i.e. a defect like slow load times will be more painful for them, because they have to work with their tool regularly and take on larger workloads on an ongoing basis, before developers can ever get their hands on it.

Notice that there’s still the benefit through centralization of tool developers: central contact point for tool needs, cultivating expertise in developers, knowledge of shared code base, understanding of infrastructure and contact points for infrastructural resource needs; however, you avoid the weird customer disconnect that comes with time slicing a traditional tool team.

Tools developers may also find that they enjoy the team that they’re working in so much that they request to stay on that team! How awesome of a pitch is that to new hires? “Do you have a strong background in software development? Work closely with established software experts, make connections to people who will love you when you’re done awesome-ing their lives, and take a whirlwind tour of the company within one year.”

Footnotes

[*] Yes, I’m suggesting you digest my mind-goo.
[†] For some definition of par.
[‡] I’m calling them operatives now, because their roles are different from tool developers, as you’ll see.
[§] It is beneficial if a small seed of hatred for the manual task begins to develop, though care should be taken not to allow operatives to be consumed by said hatred.

Virtues of Extreme Programming practices

July 12th, 2010

Aside: I’ve changed the name of my blog to reflect a new writing approach. I’ve found, with good consistency, that being near-pathologically honest and forward is a boon to my learning productivity. Sometimes it causes temporary setbacks (embarrassment, remorse) when I step into areas that I don’t fully understand, but the increased rate of progress is worthwhile. For example, this approach should help me get some SQRRR accomplished more readily, as I can get more ideas out in the open and don’t need to feel like an expert on everything I write about.

In my limited experience with Extreme Programming (XP) practices, I’ve felt it was a long-term benefit for myself and my teammates. Unfortunately, because of XP’s deviation from the more standard programming practices that I was taught, the activities originally carry a certain weirdness and unapproachability about them. Tests up front? Two people writing a single piece of code? Broadcasting the concrete tasks you accomplished on a daily basis?

After shaking off the inevitable willies, I’ve found that those activities improve relationships between myself and other team members and help to solidify code understanding and emphasize maintainability. From what I’ve read, this is what the developers of XP were trying to help optimize: the productivity that results from accepting the social aspect of coding. It is strictly more useful to form good working relationships with humans than with rubber ducks.

A nice secondary effect from the social coding activity is an increased flow of institutional knowledge. Everybody knows little secrets about the corners of your code base or have figured out optimized workflows — somewhat obviously, interpersonal flow of info helps keep more people in the know. When it takes five to ten minutes to explain a code concept to someone, both parties start to get the feeling it should be documented somewhere.

It reads a bit dramatic, but this snippet from the XP website has been fairly accurate in my experience:

Extreme Programming improves a software project in five essential ways; communication, simplicity, feedback, respect, and courage. Extreme Programmers constantly communicate with their customers and fellow programmers. They keep their design simple and clean.

The cons that I’ve witnessed are some minor bikeshedding and the increased overhead that seems to accompany these tasks:

  • Stand-up meetings take time from coding.
  • Unit tests take time away from “product code”.
  • Pair programming has social transaction costs.

On the other hand, I’ve also witnessed these costs get amortized away:

  • Small amounts of bikeshedding can get the issue out in the open instead of letting it simmer in a passive-aggressive stew. Reasonable people seem to handle this just fine.
  • Telling other people on your team are what you’re doing feels inclusive and keeps everybody in the know. (Plus, you can do it in twenty seconds per person once you’ve reached the steady state.)
  • Even a single, representative unit test forces some loosely coupled design-for-testability thinking and shows how you intend for the code to be used.

At Mozilla we seem to have a decent code review process down, which is one of my favorite social coding practices when it’s done well. At the moment, my team doesn’t seem too keen on some of the other practices I’ve found helpful, and it’s certainly not something you should force. In any case, I’m happy to be the guy who talks about how great I’ve found these practices when the topic comes up until somebody comes around. ;-)