the $150k solution

December 11th, 2011

An article was published yesterday in one of Austin’s local papers about Austin’s tech talent shortage. I was job hunting just a couple months ago and get a lot of calls from recruiters and hear about friends’ companies who are hiring and I think it’s pretty damned accurate. And by accurate I mean that it points out how fucking ridiculous some of these companies are being. Flying out to SF to try and steal engineers away but not being willing to match their salaries? Seriously?

Dear Austin companies: It doesn’t matter whether you think developers are a commodity. You can’t treat them that way. You don’t get to set their market value – the market does that. You can’t compensate them with pool tables and tacos. You can’t ask them to spend an extra 20 hours a week making up for your shitty management decisions or commuting to some isolated office park that was cheaper to rent than something on a goddamned bus route. There is a give and take and nobody’s obligated to come work for you. Balance is necessary in all business relationships, even relationships with less business-savvy nerds.

money doesn’t matter until it’s not there

One of the most damning quotes in the article is, “I’m not going to pay the California wages, which can be 30 percent higher.” I’ve had a large number of bosses who believed for some reason that the chance to contribute to what they were building should be more important to me than my compensation for doing so. That’s fucking ridiculous. If I’m making you rich, you pay me to do so. You’re the one getting the big payoff at the end, not me.

Austin companies should be thinking in terms of how much further a California salary will stretch here and using that as a negotiating tool when they offer talented engineers what they’re already making – minimum – to relocate. If those engineers are relocating from the damned Yukon, same thing, because I can fucking guarantee you that if they’re open to relocating they’ve got an offer from somebody in SF, too. A higher salary is going to cost you less than hiring shitty people or not hiring anyone. There are a gazillion blog posts about this from people who actually run software companies, not bratty engineers, so, hey, don’t take my word for it. But if you think you should get some kind of discount cause your business is based in a town that’s figured out how to put scrambled eggs in tortillas, better disabuse yourself of that shit.

your office is not magical productivity land

There’s nothing that makes me sadder than talking to an awesome company about a job, knowing that they want me to move to San Francisco or drive to north-goddamned-Austin every single day and I’m not gonna do that. Is that stubborn? Yes. But I have a challenging housing situation I can’t get out of and commuting goes against the way I choose to live my life. If it was just me, that’d be one thing, but it isn’t. Lots of people can’t move, or don’t believe that spending two hours on the freeway every day is a healthy lifestyle. But guess what! We don’t expect you to move your whole office to wherever it is we happen to live – we’re generally happy to telecommute!

If I could relocate, Austin sure as hell wouldn’t be my first choice. I moved here when I did because my ex-husband and I had blown most of our savings on our wedding but were desperate to get out of Seattle, and I knew the lower cost of living here would make it possible for me to support both of us if he couldn’t find a job for a while. If I’d been single, more confident in my skills, and sans wedding debt I would have moved to San Francisco or New York. Austin’s lovely, but I like being able to get a decent bowl of ramen. And take public transit. Of course I’ve since fallen a little bit in love, but when I moved here everything was brown and ugly and covered in strip malls and I had to keep reminding myself of the spectre of Seasonal Affective Disorder waiting for me if I turned tail and went home. Anyway, it’s not objectively everyone’s cup of tea. Maybe somebody wants to live in middle-of-nowhere fucking Montana all River Runs Through It. Maybe they’re the best Python dev the world’s ever seen. You don’t know.

There’s a popular theory that people are most productive when they all sit together in big echoey rooms at communal tables with no dividers between workspaces. I think that’s horseshit. The only people who are “productive” in those settings, in my experience, are the type of management people who feel compelled to come over and interrupt you in person rather than send you a fucking email you can look at once you’re done tracking down a bug six levels of callbacks deep. YOU KNOW? If your company lacks the tools to communicate remotely, it’s highly probable it can’t communicate at all. As for exposing devs to their peers, I agree it’s a pleasure to work next to other JavaScripters, but I also see better peer interaction between people who don’t work for the same companies every day on IRC than I have in any office I’ve ever been compelled to go to.

Companies who don’t demand that engineers come to them have power right now. Over the past two years I’ve switched jobs a number of times and have interviewed a shitload. I’m not the best, but I’m good, and I’ve only been turned down twice. Guess what both companies had in common? If you think your company is getting the shit end of the supply and demand plunger, try opening your hiring up to remote employees.

do something interesting

This is harder. There are a lot of companies using the latest, hottest technologies that probably won’t exist in a year. There are lots that do pretty boring shit, are tied to legacy code, but are stable and responsible. This is an Austin-wide problem, but also a problem for individual companies to solve. To attract technical talent, a city just has to have cool technology happening somewhere. It just does. Nothing is exciting when all you and your friends have to talk about is the best jQuery plugins to use in building a fly-by-night groupon clone. People get excited when one of their peers is implementing Node in production or switching over to NoSQL or whatever. It makes nerds feel competitive, it makes them more engaged because they don’t want to be left out of playing with the latest coolest thing, so they go home and put something on github if they can’t do it at work. But if all the companies in town are focused on money first and technology never, too many “tech” conversations are about funding and other business-y shit which gets really boring, at least for this engineer.

If your company makes something entirely uninteresting, that’s fine. We need useful software to fill niches, or our whole industry suffers. If you make a boring thing, there are two things you can do to still attract good talent. First, if you don’t need a senior dev, don’t hire one. Hire a junior person, give them the chance to architect small changes to the system, help them grow as an engineer. If you do need a senior person, hire them, but carve out 10% or 20% time for them to do open source stuff or personal projects or whatever. And don’t get all butthurt about paying them to do things that “don’t create value”. You probably use open source software. Your devs’ skillsets need the support of a larger community to stay current. And bored developers quit producing and, well, quit. If you can’t make your product interesting, that doesn’t mean you can’t make your engineers’ jobs interesting, and you’ll benefit indirectly.


It’s hard not to read an article like this one and feel smug, but it’s also hard not to feel frustrated. At the end of the day, we’re workers. We’re some of the only workers in this economy with any control over our professional lives, who don’t have to live in fear of unemployment. It shouldn’t be possible for companies to bleed talented people dry in exchange for the minimum possible compensation and bullshit perks like foosball tables, yet somehow it is.

A former boss of mine is quoted in that article, and I know he’s one of the good ones, and treats his engineers as respected employees who play a huge role in the success of his company. There’s an opportunity in this for executives like that, clearly, because so many more bring only a mediocre idea and a pile of VC cash to the table and expect to pick up developers as though we were all standing around idle on the corner outside Fry’s. There’s no more sense in competing with those people for bargain-basement talent than there is in working for them, and I think it’s pretty easy to avoid having to do so for companies who can be a little more flexible.

“girl” power

November 16th, 2011

I just watched a short video called How to Get More Women in Tech in Under a Minute. The speaker, Caroline Drucker, is making a point about the toxicity of the word “girl” and how it hurts the cause of women in technology. Her argument is that every time we refer to ourselves as girls, or allow others to, we lose ground in our profession. I’ve got two problems with this. First, it wildly oversimplifies a super complex issue. Second, it’s in opposition to the goal of including more women.

I admit it sounds good on the surface, and it would be wonderful if all we had to do to close the gender gap (she’s not literally saying that) was to stop calling ourselves girls. You could say I’m predisposed to disagree, having started an organization that uses the word “girl” in its name and organizing the Austin chapter of a second. And I do disagree, but not just cause I don’t want to think of myself as the kind of woman who undermines the power of women collectively. Nope. The word “girl” in Austin All-Girl Hack Night is there quite intentionally.

I know women who are driven just as crazy by the use of the word “girl” as the presenter and the other women she references, and they have every right to feel that way. But I’d like to speak for the other side, as someone who frequently refers to herself and other women as girls, and is much less likely to refer to “men” than to “boys”, “dudes”, or “guys”. As a feminist walking what I perceive to be a damned thin line between making my point and making people uncomfortable, I choose casual language over formal pretty much every time.

Ms. Drucker touches on something I think is worth expanding on, which is the difference between us when we’re being women and when we’re being girls. And I think she implies that all of us – as adult women – are sometimes both. We never stop being grown-ass women, that is, but that doesn’t prevent us from acting like girls. Exactly like our male counterparts when they’re being boys, we’re fallible, we’re vulnerable, we’re sometimes immature and entirely too human. We might wish it would, but this doesn’t stop we we cross the threshold into our offices. Like it or not, sometimes we’re girls at work, too. Being a girl sometimes is part of being a woman.

But, fine, certainly male professional associations wouldn’t highlight those weaknesses. I have a question for women in tech organizations, though: where has all that careful naming gotten us? Have the organizations, conferences, articles, and movements that use the word “women” instead of “girls” or “chicks/chix” been markedly more successful? Anecdotally, it seems like no. At minimum, the two distinctions succeed in different ways.

Cause here’s another thing about women: for a long time, women weren’t supposed to hang out with men. Girls, by contrast, have in almost all cultures been lumped together with boys. Girls and boys are temporarily sexless, they’re treated more similarly than they probably will be for the rest of their lives. One good thing about the words “girl” and “boy” is that each implies its complement. When it comes to organizations that exist to integrate women with their male peers, I’d argue that “girl” is exactly the right word.

So those are the logical reasons I reject Ms. Drucker’s argument. The subjective reason, and what I was alluding to when I said I think her argument has the potential to hurt rather than help, is this: women are not all the same. Even feminists are not all the same, nor are people who choose technical professions. You can’t tell other people what to call themselves. There’s a long debate over whether you can change the power of a word like “bitch” by reclaiming it and using it in a way that’s casual and not derogatory. If we can’t settle that, we can’t tell other women which neutral, relatively unweighted word they get to label themselves with. Not all of us feel comfortable as women. Some feel more comfortable as girls. While “girl” may be a diminutive, a girl is also someone who climbs over fences and shaves half her hair off before someone catches her and draws on the walls.

I’m very much against the idea that women need to behave more like men in order to succeed, but there’s one thing men definitely get right: they respect each others’ independence. As women, we seem to be raised to do the opposite. There is no Catcher in the Rye for us, no On the Road. To me, telling women they’re fucking something up if they don’t call themselves women is like telling them they’re shitty moms if their kids go to school in hand-me-down clothes. The western tradition of passing mores down matrilineally and holding women to a standard we’d never expect of men seems to me to be making an appearance here, and that’s not constructive. You don’t tell other women who to be. You support whoever they choose to be. That’s how we get more women. If you don’t believe me, consider the “geek room” study, and how our industry’s been affected by the stereotype of the nerd. We already have women ignoring their technical calling because they feel they don’t like D&D enough. Let’s not make the ones who get past that barrier feel bad for being insufficiently earnest feminists.

In closing, I want to explain my personal use of the word “girl” in Austin All-Girl Hack Night. There’s a Salt-N-Pepa song – Expression – that contains these lyrics:

Yes, I’m blessed, and I know who I am
I express myself on every jam
I’m not a man, but I’m in command
Hot damn, I got an all-girl band

That’s why Austin All-Girl Hack Night is called what it is. Cause I listened to a lot of Salt-N-Pepa as a teenager and that’s where my picture of feminism comes from. It doesn’t mean every woman who comes to hack night has to agree, but it is in some way meant to suggest a more casual relationship with feminism and professionalism and a stronger emphasis on community and camaraderie. And, yes, even immaturity. It’s hard work being a grown-ass woman all the time. Sometimes it’s nice to get a bunch of girls together and draw on the walls. Maybe we get more women in tech by telling them they’re allowed to be girls sometimes and don’t have to be perfect women.

calling the github API with node.js

September 4th, 2011

Updated: when I originally posted this, I wasn’t able to connect to the github v3 API. That’s fixed now, and several pieces of code are different as a result. Namely:

  • removed http.createClient() – that’s deprecated, oops
  • require the https module
  • save the oauth token in the session
  • completely change the way the API gets called

Sorries.

For the past several days I’ve been working on getting a list of github repos for an authenticated user using node. Seems like a pretty simple problem, right? For someone more seasoned in the various technologies involved, it no doubt is. But in my particular case.. well, refer back to the “several days” part. As an outsider when it comes to node.js, I find it damned challenging every time I try to create a node app to do even the simplest things, and there’s a lot of research involved, and frequently I find myself with seventeen tabs open cause I’m combining info from a bunch of different sources to get the thing I want. In service to anyone else who might be experiencing the same thing, I thought I’d write down how I got this all working.

1. install all the things

For completeness’ sake, let’s start at the very beginning. You need node and npm. I like to get the precompiled version with npm, cause if I wanted to compile shit I’d still be a Java dev. In addition, we need to grab some npm modules. You could list these out in packages.json, but since I’m still testing out and occasionally discarding various modules, I just grab all of mine one-by-one. Go with what you feel. The modules needed for this example are:

  • express
  • everyauth
  • hiredis*
  • connect-redis*
  • jqtpl**

* The redis stuff isn’t used in this example, but it’s where the session info is theoretically getting stored, and if you use my code as-is, it’ll probably break without it.
** Assuming you know how to write the template syntax and pass in whatever data you need, substitute any template engine you like.

If you haven’t used npm (did I say completeness? I meant completeness, baby!), it’s very easy, and quite frequently works without a hitch. Open up your terminal and navigate to the directory where your site will be stored. On the command line, for each module you want installed, type:

npm install [name of module]

If your npm version is up-to-date and you typed everything correctly, you should find that you have a folder called node_modules and it contains a sub-directory for each module you just installed.

2. set up express structure and import modules

I know a lot of JavaScript devs who came to JS through jQuery. In the same way, I came to node through Express. If you’re used to using a JS library, it can be an unpleasant shock if you have a reason to write out an XHR without one’s help to remember how much damned code is actually involved in that. The way a library abstracts away the repetition and fallbacks inherent in an XHR, Express abstracts out some of the extra code needed to provide basic handling of requests to your server.

In the root of our directory, let’s add a file called app.js. This is what we’ll actually run when it’s time to fire up the server. At the top of the file, we want to import all those modules we just installed:

var express = require('express'),
	app = express.createServer(),
	http = require('http'),
	https = require('https'),
	connect = require('connect'),
	redis = require('connect-redis')(express),
	everyauth = require('everyauth'),
	sesh = new redis();

Now we have access to all the objects we’ll need to put our app together. You’ll notice we got a couple modules for free as part of node or Express. You may also notice that some modules we refer to statically, while others need an instance created. If you didn’t notice, well, now you know.

3. create a config file

Because we’re connecting to an API and storing session information, we’re going to need a bunch of keys and stuff. The usual structure of an Express app has us put supporting JS files in a lib directory, so let’s make one of those in the root of our app and create a new file called config.js. We’ll dump all our super secret passwords and stuff in there, and that way if we want to put this up on github later we won’t have to go through our main code looking for sensitive information. To have something to put in the file, we’ll need to go over to github and register our app.

If you have a hosting account with Joyent, Heroku, Linode, Nodejitsu, or one of the other node hosting providers, or if you’ve set up node on a VPS, you’ll have a public URL you can supply to github as the callback. If not, you’ll need to make a fake URL for localhost. My callback URL is http://local.host:8001. To make that work, I also had to map 127.0.0.1 to local.host in my hosts file (note that that link has you using nano to edit it – I like to navigate to the directory and type edit hosts to make it open in my default text editor, which has a GUI, like nature intended) by adding the line 127.0.0.1 local.host.

After registering with github, we should have a client ID and a key. We’ll add that, and a couple other things, to our config file:

var config = {};

config.gh_clientId = "[client ID from github]";
config.gh_secret = "[secret from github]";
config.redis_secret = "[anything you want]";

module.exports = config;

That’s all pretty pulled-apart, but it’s just JS, so if you want to restructure it so it’s just one line, be my guest. If you haven’t worked with modules, you may want to note that exports thing at the end. That defines what our module will return, which is important, since we – in all cases, as far as I know – treat any external files in node as modules.

Now that our config’s all set, we can add another line to the variable declarations at the top of app.js to import it: config = require('./lib/config'). (Note that it doesn’t care about the file extension.)

4. set up basic express app

Now let’s add more Express stuff to app.js. This’ll give us some basic routing, rendering, and storing of our sessions.

app.configure(function(){
    app.set('view engine', 'html');
    app.set('view options', {layout: false}); // we can use a master layout, but I turned mine off
    app.register('.html', require('jqtpl').express); // oh hey, remember this guy? importing him inline to mix things up
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({store: sesh, secret: config.redis_secret}));
    app.use(everyauth.middleware()); // pretend you didn't see this yet
});
 
app.get('/',function(req,res) {
	res.render('login');
});

app.get('/board',function(req,res) {
	res.render('board');
});

app.listen(process.env.PORT || 8001); // use whatever number makes you happy

You’ll find this sort of basic stuff in pretty much any Express app you look at. We’re configuring our app to use our template engine and look for the file extension our templates will be using, set up some stuff to support sessions, and add in everyauth, which we’ll look at in a second. We’re also creating a few routes for our app, and for right now all those do is render the templates without data. Finally, we tell the app which port to listen on.

Since the two templates we want to render – login.html and board.html – don’t exist yet, it’s probably a good time to create them. By default, Express will look for these in the directory views. Here’s what the bodies of mine look like:


<a href="/auth/github">sign in with github</a>

hey there, {{= username}}!
<br/><br/>
your repos:
{{each repos}}
<p>
	<a href="{{= $value.url}}">{{= $value.name}}</a><br/>
	{{= $value.description}}
</p>
{{/each}}

You can create those in the views directory and be done with them, or change them up a bit to suit your own plans for displaying github data. All mine do is provide a login link, using a route that everyauth will create for us, thanks to that everyauth.middleware() line in our app configuration, and then display some data we don’t currently have. So hey! Let’s work on that.

5. configure everyauth

everyauth provides a fairly automated way of authenticating our user with github (and a bunch of other sites – check their github for a full rundown). All we really need to do to make the module work is give it our app’s credentials from github, add the authenticated user to the session, and provide a path to redirect to once everything’s done. I’m adding another piece which overrides the default logout behavior from everyauth’s middleware to remove the user ID from the session. I’m pretty sure you could add this block of code almost anywhere, but I have mine between my block of variable declarations at the top and my app configuration:

everyauth.github
  .appId(config.gh_clientId)
  .appSecret(config.gh_secret)
  .findOrCreateUser( function (session, accessToken, accessTokenExtra, githubUserMetadata) {
    session.oauth = accessToken;
    return session.uid = githubUserMetadata.login;
  })
  .redirectPath('/');
 everyauth.everymodule.handleLogout( function (req, res) {
  req.logout();
  req.session.uid = null;
  res.writeHead(303, { 'Location': this.logoutRedirectPath() });
  res.end();
});

If you do check the documentation out on github, you’ll see that the code above is almost entirely lifted from their examples. All we’re really doing differently is adding (and removing) the property uid to our session.

6. add logic to the routes

If you tested your app right now (from the root directory of your site, in Terminal, just type node app.js, then open a browser and go to http://local.host:8001), you ought to see your login page with a link to authorize your app via github. After you do that, you’ll get redirected back to.. your login page. Which obviously sucks. So now let’s flesh out our routes, starting with the root of the site:

app.get('/',function(req,res) {
	if (req.session && req.session.uid) {
	    return res.redirect('/board');
	}
	res.render('login');
});

This is super simple. Our rendering of the login page is still there, but now we’re going to check for the presence of that uid property in our session. If it’s there, we redirect to our /board route. If you check out your app now, assuming you’ve already authenticated, it should send you to board.html. Which doesn’t do anything at all without some data, so let’s beef that up now.

It’s worth noting that there are node modules that handle connecting to github’s API for you – github-api and node-github. I didn’t use them because 1) connecting to the API is actually pretty easy once you figure out how it’s done, and 2) they both use version 2 of the github API, which is now on version 3. For my app, I need version 3, so what we’re going to do is call the API manually, which means using node’s built-in https module:

app.get('/board',function(req,res) {
    if (!req.session.uid) {
        return res.redirect('/');
    }
    var repos,
        opts = {
			host: "api.github.com",
			path: '/user/repos?access_token=' + req.session.oauth,
			method: "GET"
		},
    	request = https.request(opts, function(resp) {
    		var data = "";
    		resp.setEncoding('utf8');
		resp.on('data', function (chunk) {
			data += chunk;
		});
		resp.on('end', function () {
			repos = JSON.parse(data);
			res.render('board',{username: req.session.uid, repos: repos});
		});
    	});
    request.end();
});

That may look a little messy (probably there is a nicer way to write it), but it’s not doing anything too tricky. The first if statement checks if the user’s authenticated and, if not, sends them back to the login page. After that, we create our empty repos var and an object literal containing the properties of the request we want to make – the hostname, path, and method. Then we create/fire our request using https.request(), passing it the settings we defined and providing a callback. Finally, we end the request.

Every time we get a response from github, we’ll add the data to an existing buffer. When we’re done getting responses, we’ll parse the data we’ve received and render our template, passing in the username and our array of repositories. If you test out your page again, you should see your github login and a list of your repos. You can use this same technique to get and display any of the data publicly available through the API and things private to your authenticated user.

ps:

I’m working this stuff out as I go (obvs), so I’d love your feedback, especially if what’s above doesn’t work for you, or you’re trying to connect to a different API and this example doesn’t map very well to that. Also, I’m going to be talking about working with node as a front-end developer at the next jQuery conference in Boston, so if you’re also a front-end dev just starting to play with this stuff, I’d be really interested to hear about your experiences and any barriers you might have encountered.

widgets for third-party sites

July 4th, 2011

For the past couple weeks or so I’ve been driving myself crazy researching the ways people are developing widgets to run on other people’s sites. I’ve been writing and rewriting the same piece of JavaScript on the daily as I find new information or start to doubt the information I’d decided previously was The Right Way. Though a big part of the problem has been the 90 gazillion blog posts and presentations tackling the subject in whole or in part, I thought I would write down what I came up with. Mostly to get some feedback on it, but also just to kind of collect that research and its outcome.

General structure

This was the part that I found the least information on, and I don’t really get why that is. If you have this piece of code running on someone else’s site and you don’t have concerns about where the HTML or the CSS or the data is going to come from, my understanding of modern terminology leads me to believe that what you have, sir or madam, is a plugin. Anything bigger than a plugin needs other stuff to support it, and unless you want to manage all that stuff as long-ass strings in JavaScript, I’d assume you’d keep it in a different file.

However, your buddy with the third-party site probably did not ask you to add as many extra requests as possible to the loading of the page housing your widget. It seems like minimizing the number of times your widget goes and gets other files or objects from your own servers would be a primary goal. The way I’ve decided to handle this is to err on the side of efficient requests where possible and to make a bunch of requests where I don’t see a good way around it. Specifically, the static data – HTML and CSS – lives in its own files on a node server, but when the third-party site requests the widget code, the contents of those files get added to the JS as variables. Data has to be collected separately, but I’ll get to that..

The HTMLs

I’ve seen a lot of people who seem to be suggesting that when your widget calls for data, it should get it already wrapped up in its HTML, which I hate. It’s just a little more processing to run pure data through a template, and it allows the consumer of the widget the option of easily switching out the markup if you expose a config property that provides a path to a customized template. Because creating a view model on top of the pure data seemed like a giant pain in the ass, I used John Resig’s Micro Templating. It’s small and efficient, bakes in caching of the templates, and allows enough logical flexibility to cover pretty much any need.

Configs

The widget I’m working on needs a good deal of setup info. Not only does it need data corresponding to anywhere from 1-n different objects, it needs to be able to find the places where those objects are rendered and be able to choose among a few options for how the widget itself will get rendered. It also needs normal widget stuff like an API key and all that. This adds up to one big-ass config. Asking the consumer to append all that data to the querystring that loads the widget code is possible, but seems awfully fragile to me. Better that they just keep it in a big object literal and the widget goes and finds it once it’s loaded. However, because all the config data isn’t part of the additional request, we have to deal with complicated cross-domain messaging issues when we do get the data, instead of the data being pre-loaded like the HTML and CSS.

Cross-domain stuff

By far this seems like the piece of the equation with the most information and the least clear answer. There are a few simple, modern ways around the cross-domain problem, but they only work with newer browsers, and IE, in a move surprising 100% of no one, has decided to implement their own version of the standard in their newer offerings. I actually made a flow chart trying to describe the choices to be made in picking a solution stack (and a stack is what you need, unless you somehow can manage to only support WebKit) that seemed to get some lulz, so I assume it’s close enough to accurate to at least be funny.

Because I need to send and receive a decent-sized chunk of data, but had the option to break it up into smaller requests/responses, I ultimately decided to use CORS and JSONP where CORS was unsupported. Previously, I’d ultimately decided to try and send/receive all the data for however many objects the widget needed to be rendered for at once, but I was skeptical about fitting all that in the URL of an iframe. So now I make one request per object and that seems like the best solution for making good use of resources and maintaining my sanity. I looked into easyXDM, but it seemed to me in reading the docs that I was going to need to manually manage all the same fallbacks, just accessed through a nice clean abstraction. I may have misunderstood that, but once I figured out how I could accomplish my goals without reading the documentation necessary to understand how that tool works, I decided to just try to get it done DIY-style.

External libraries

I had a fun debate with some friends on twitter about the merits of using jQuery vs. using a microlibrary or something completely hand-rolled. My point about jQuery was that there are decent odds that the third party site would be using it or that the end user would have it cached. I still think that’s true, but I needed so damned little of it that it seemed better to just write a couple of custom functions to do things like get elements from selectors. The totally efficient thing to do would be to make the signatures of those custom functions match jQuery or some other common library so that I could easily switch between them, but the code has to get loaded either way and now I have no external dependencies. Although I did copy and paste other code, like Micro Templating, into my widget code. That feels icky, but also efficient.

Lots of thinking for very little processing

I still feel weird that so much frustration went into this project, because it actually does so little. The external site calls the node.js server, which responds with the widget code and the static files embedded within that. It iterates through the objects defined in the config, makes its request to get the data for each, runs it through a template, and inserts it into container defined in the config by either a class name or an ID. The init() portion of the code may be the smallest piece. Did I do that right? I have my doubts, but I’m also not sure what I’d change. If you have comments, I’d love to hear ‘em.

no country for old hackers

July 1st, 2011

This was actually a presentation that I was hoping to submit to a conference I really wanted to speak at. The reason I didn’t ultimately submit anything is the same as the topic of the presentation/post, in part. How’s that for meta? And since I’ve been thinking of it as a presentation, I’m just going to write it like I’d say it. Sorry if that’s weird.

Who here would consider themselves an old hacker? Who’s here reading this because those words resonated? Some of you, I hope, or this might not make any sense. If you’re a web developer, calling yourself an old hacker is kind of ridiculous, in the scope of computer programming as a whole. But, relatively speaking, I think we all know what that means. It means you tested in Mosaic. It means you had the lecture about how there was no upgrade path for IE5/Mac and therefore we were going to have to support it until the end of time. It means you’ve been guilty of table-based layouts and you had your mind blown by “To Hell with Bad Browsers” and then again by AJAX. Or maybe it just means you remember the browser wars and found it difficult to trust $ over getElementById.

At any rate, here you are.

I want to ask you something. I don’t want the answer you’d give in an interview, but the real answer. I want to know if it’s the same as mine. Why did you keep doing it? Web development, especially for front-end people, was fucking idiotic at the outset. Things like presentational attributes were a revelation. The whole world was in Times New Roman. The power of the web was less than the power of the manual lawn mower your parents had in the shed out back and were yelling at you to step away from the computer and get to work with. But you, you were on Geocities, or Angelfire, or some college server, or your own server, if your freak flag flew that way. You were writing HTML, even though HTML was giving you fuck-all in return. Why did you keep doing that?

True, at that point the web was young, and the only people on it were our people. It was exciting to be able to put something out there and know that anyone anywhere in the world could theoretically end up seeing it. This was before endless privacy debates about whether google was stealing our thoughts – at the time, it was amazing just to have a platform.

Magical though it was to participate in that, at least for me, sticking with it ultimately came down to something else: the mythical wild west of computer programming. In college I had to read “Where Wizards Stay Up Late” and though that book is a little long on facts and short on poetry, the picture it painted was something I very much aspired to. At the time, I didn’t know there was an alternative. Without knowing it, I was used to doing cutting-edge shit by that point, because the only coding I’d ever done had been front-end web dev. We’ve since disavowed tables for layout, with good reason, but think back for a second on how much it changed when you realized everything didn’t have to be laid out in a single column, before float, when <br> was your only tool. That, my friends, was a hack. A messy one, but one that served us well at the time, and one that allowed our field’s better half, web design, to progress despite the available tools. Best practices were an extremely science fiction-y joke. There were few rules and endless constraints. If you wanted something, you had to go out and kill it for yourself.

Maybe you think it’s irresponsible of me to romanticize that era. After all, it produced little of lasting quality and we spent years weening ourselves and our superiors off those bad habits. It’s not the habits I miss, though. It’s the fun. It’s the discovery. It’s the hacking shit together and hoping it holds.

So this is why I didn’t submit this proposal. This is the question I’m scared to ask. What today offers that same unlimited potential? We can make shit that would’ve been unimaginably awesome to our 17-year-old selves, but everything’s reversed. We have plenty of (good, useful, valid) rules and very few constraints. The shortcuts have signs telling you to stay on the path strapped to chains that prevent you ignoring that good advice. There is always a right way. The west has been won, the territory has been discovered and cartographed and gentrified. And we benefit, certainly. The web benefits. The world benefits. Everything got better when JavaScript libraries started popping up. It got better again when browsers began implementing native features to do the shit we used to hack together. But now what do we do with ourselves?

I spent about a year being really, really mad at A List Apart. I used to wait for new issues to be published to see what the next FIR or sliding doors would be. And then, at some point, every issue was about content editing or UX. It took me a while to get it: what else were they supposed to write about? They led the charge and they won. We won. Once everyone started agreeing, we stopped needing hacks. We stopped reading PiE and ALA and we all went and downloaded jQuery. Then we stopped downloading jQuery and started downloading microlibraries cause, shit, everything’s native now. It’s strange and lonely to find that no one is arguing with you anymore.

I suppose ALA had stopped pushing the envelope because ALA’s bread and butter was HTML and CSS and that envelope wasn’t gonna be pushed no further. JavaScript, the toy language, had matured in the shadow of its siblings’ growth spurts and was suddenly very sexy. For me it remained sexy right up until CoffeeScript. And, if you know me, you know I do not mean CoffeeScript replaced JavaScript in my affections. I heard Brendan Eich talk about hopefully implementing pieces of CoffeeScript in JavaScript at jsconf and my heart just sank. If you straighten JavaScript’s nose and give it Lasik and put it on that paleo diet it’s not going to be the same sexy language I fell in love with. Metaphors aside, my heart sank because you can’t say anything to dispute CoffeeScript. Obviously there’s nothing wrong with making a language easier to write. The same as with Haml or SASS, no one’s making me use it. But I can’t pretend it doesn’t kill me that the most exciting thing we can think of to do with JavaScript is to clean it up to appeal to people who don’t like JavaScript.

Obviously there are still interesting problems in JavaScript beyond all those terrible little curly braces. People are doing great things with movies and animations and that’s awesome, but the field of real world use cases is pretty narrow. Node.js is fucking stellar and I love it, but it’s still server-side and it’s just not the same when no one’s ever going to see your mistakes. The bulk of the interesting problems I see right now are how we compose various off-the-shelf pieces. We move so fast, with such immense power, that it’s almost unreasonable to stop and figure out how to do these things for ourselves. In your free time? Sure. Yeah, go and rewrite the entirety of YUI or something from the ground up just for the joy of thinking about it, all on your own. As an answer, that’s almost cruel.

And that’s just the libraries and the language. What about the browsers? Imagine you did think of something in JavaScript that had yet to be coded, some essential hack that was missing from our libraries. How long would that remain relevant? All those placeholder polyfills are destined to become the latex jellyfish washed up on next year’s beaches. Our hacks are only a slightly faster solution than sitting and waiting patiently.

I’m not saying I give up, but when this entire landscape has changed completely, I’m going to miss it. I think domestication has become inevitable. Unless the web fragments again, and it’s once more us against them, I think we’re on the road to efficient and productive normalcy. Which is great in almost every way except that it’s just not as fun. The web is on its way to becoming a commodity. That awesome Wilderness Downtown thing that Google did? That was super cool. CPU fans all over the world were very, very excited about it. But my boss has yet to ask me to implement it on our site. We live for demos and proofs of concept. We go back to our dayjobs and implement someone else’s boilerplate, skip the unnecessary syntax, run the unit tests, push to the cloud and clock back out. It’s not really that black and white, but it’s never gonna be the same.

I haven’t given up. I just wonder sometimes how long we’ve got before we all have to stop being hackers and be software engineers.

separation of concerns is a bunch of bull

June 24th, 2011

A couple days ago I was booking myself some air travel. I finished filling out all the forms and submitted my payment info and finally it dropped me on the confirmation page. The confirmation itself was tiny, and the rest of the page was taken up by hotel offers, several of which were stupid expensive for non-business travel. Most were in the $100s, but one was $239. The full header text on the hotel module read, “only $239 more per night” and that 1) seemed like a fucking nonsense way to describe $239, and 2) got me thinking about templates.

I don’t know how the travel site does their templates. Probably on the server, since that’s the way most sites still do them. It doesn’t really matter, though, whether it’s client-side or server-side. There’s an opportunity to not say “only $239″ and instead say “on sale for $239″ or “a hell of a deal for $239″ or something that sounds slightly less ridiculous and emphasizes that the hotel’s best feature is not its price but like the twice-daily full-body massage and salt scrub you better get for $239. However, to do something like that would mean introducing extra logic. Not logic about data, like is this price part of a sale that will expire halfway through the user’s stay, or is this hotel also right by a convention center, but logic about how the data is displayed. So I can kind of sympathize with whoever did not put something like that into the template for the hotel module, because that particular grey area gives me fits.

As part of trying to push client-side templates down everyone’s throat at my last job, I started relying heavily on the concept of a view model – an additional layer between the template and its data that prepares all that data to be rendered. And I loathed the sort of things I was creating properties for in the view model, things like the plural form of words or what text to display if some array of objects was empty. Mostly, I loathed the fact that no matter how many fucking view model properties you create, at some point, if you want to keep your HTML in your HTML, you’re going to have to put logic in there and that’s just that. I loathed the feeling that trying to do a sincere and thorough job of “separating concerns” was tantamount to pushing a big damn boulder up a steep hill.

I have been doing this computer science shit for a long-ass time. I studied it in school for four years. I cannot think of any real world system I’ve seen in that time that achieves perfect separation of concerns. I posit that the reason for that is that separation of concerns is bullshit.

Hundreds of years ago, our superstitious ancestors would tell their willful offspring stories about monsters and demons to try and trick them into behaving in a way that an admonishment to be careful alone would not. Separation of concerns, I think, serves much the same role for developers. As a concept, it keeps us in line and without that principle our code, collectively, would without question be much more fucked. For the most part, we stick as close as we can to the protection separation of concerns offers us from the giant scary “these concerns are not separate” boogeyman who lives in the forest. But, y’all, there is no concerns-not-separate boogeyman. There is only trying hard to write nice code, or not.

Back to templates. If you count all the client-side templating engines you know of, I bet you run out of fingers. Most of them do the same thing, so why are there so goddamned many? I blame the separation of concerns mythology. Everybody wants a damn logicless templating system and as far as I can tell, no one has managed to invent one or will ever manage to invent one. The ones that describe themselves as logicless continue to have basic operators that perform logical tasks. The ones that do nothing but plug in properties or the output of functions merely necessitate the offloading of all the logic to an additional view model, and since they can’t function without that piece of the equation, I’d say they still fail to be logicless. HTML is your logicless templating engine. As soon as you begin adding dynamic information, you can kiss logicless goodbye, because logic is where dynamic pieces of a display come from.

I’m not saying that you can’t abstract every piece of display logic out into a view model. You absolutely can, and I will totally come bring you flowers in the nuthouse when you get all done with that. But you don’t change anything in doing so. One argument people like to make is that removing logic makes it possible for non-developer designers to work with the HTML, which is – sorry guys – horseshit. If your designer understands the best practices of good HTML, if he or she can do the necessary pattern matching and visualization, he or she can grasp what is template syntax and what is not and move those bits around and not break them, etc. If he or she does not, you’re going to be adding the dynamic data after they put their HTML together in Dreamweaver anyway.

There are a few template solutions that try to get around this problem by avoiding template syntax altogether and just using existing attributes of HTML. As far as I’m concerned, that’s the same damn thing, just as fragile and problematic, only with the additional penalty of having all the template infrastructure continue to exist in the final rendered product. If your designer can fuck up a template tag, they can fuck up a CSS class or data attribute.

So here’s the thing. The concerns that we work so hard to separate are intrinsically linked. It’s not impossible to abstract them away from each other, but they still maintain some awareness of each other. The view – the HTML – cannot be separated from the data in contains. It’s not an empty vessel that can be filled with anything, it’s marked up to have semantic meaning and an appearance that increases the utility of the data displayed. You show me a completely dumb view and I will show you an interface that fucking sucks. There should be logic in HTML, if the HTML isn’t static. It should react to its contents and show different things in different ways. When the changes are big, hell yes, create different templates and let the controller determine which to display. But I firmly believe that, when you get down to things like replacing the word “only” with something that makes more sense, trying to achieve perfect granularity is going to make you crazy and offer very little payoff.

Something that is “only” $239 is not a different type of object than something that is “on sale for” $239. It’s not in a different state. It’s stored in the same table in some database. The same type of object carries it around on the backend adding properties to it. It’s delivered to the client with the same JSON structure. It’s displayed using the same markup and the same styling. The only difference is a couple of words, words that don’t affect the data, that have been pulled out specifically for the purposes of display. Why not let the fucking template handle that? There are plenty of other places that logic could go, but ultimately it’s a view model or the view itself. I’m tired of adding tiny little things like that to view models, or worse, creating view models specifically for them.

Separation of concerns is a fantasy. It’s a very useful fantasy that guides us to produce better code, but like all fantasies it’s still fundamentally bullshit. From now on, when the only reason someone can give me for doing something or not doing something is, “But separation of concerns.. !” I’m going to start calling that what it is.

nested callbacks in jquery begone!!

June 1st, 2011

A week or two ago I noticed a bunch of people having trouble because of their nested callbacks, or with flow control in general, in jQuery. I said something about this on twitter, saying people should use jQuery’s Deferred object, and several people commented that Deferred is a really difficult concept to explain. I kind of disagree. Or rather, I think the difficulty comes from how we’re trying to explain it. So I wanted to share my experience, which begins not with “Oh jQuery has this new cool Deferred thing I guess I should go figure out WTF that is,” but with me doing lots and lots of nested callbacks.

I had this application that needed to send a bunch of updates to the server, and then redraw. The structure of the data being updated was sort of like object.rows[n].images[], and all those pieces – the parent object, each of its rows, and the images for each row if present – had to be updated via their own API calls. So the code looked sort of like this:

app.saveObj = function(obj) {
	obj.rowsToSave = obj.rows.length;
	$.post(someURL,obj,function(data) {
		$.each(obj.rows,function() {
			var row = this;
			row.parentId = data.id;
			obj.imgsToSave += row.imgs.length;
			$.post(otherURL,row,function(data2) {
				$.each(row.imgs,function() {
					this.rowId = data2.id;
					$.post(uploadURL,this,function() {
						obj.imgsToSave--;
						if (obj.imgsToSave == 0) {
							obj.rowsToSave--;
							if (obj.rowsToSave == 0) {
								app.renderObj(obj);
							}
						}
					});
				});
				if (row.imgs.length == 0) {
					obj.rowsToSave--;
					if (obj.rowsToSave == 0) {
						app.renderObj(obj);
					}
				}
			});
		});
	});
};

Or something like that. That’s essentially pseudo-code, and I know there were lots of functions that abstracted certain parts of that out, but it was more of less like that. I know there was some goofy shit with passing references to parents and parents-of-parents around in the callbacks, and those counters were definitely in there (unavoidably, I think). That’s nuts. At the time I’d never heard of deferreds or promises, and I thought flow control was a feature of shower heads. But even totally ignorant of the real solutions, I knew enough to feel immensely dirty about my own.

I think there are a lot of people in that same boat right now.. There are a couple different solutions that I learned about along the way, but if you’re using jQuery, the Deferred object is kind of the most obvious. I formed that opinion thanks to these resources, which you should totally check out if you haven’t:

(Ordered by when I saw them)
Rebecca Murphey’s post Deferreds coming to jQuery?
Eric Hynds’ post Using Deferreds in jQuery 1.5
Dan Heberden’s jqcon presentation Deferreds – Putting Laziness to Work

Looking at the mess of code above and knowing what I know now, here’s how it could be rewritten to be somewhat less shameful:

app.saveRows = function(obj) {
	var d = new $.Deferred(),
		count = obj.rows.length;
	$.each(obj.rows,function(i, row) {
		row.parentId = obj.id;
		$.post(otherURL,row,function(data2) {
			count--;
			$.when(app.saveImgs(row))
			.then(function() {
				if (count == 0) {
					d.resolve();
				}
			});
		});
	});
	return d.promise();
};

app.saveImgs = function(row) {
	var d = new $.Deferred(),
		count = row.imgs.length;
	$.each(row.imgs,function() {
		$.post(uploadURL,this,function() {
			count--;
			if (count == 0) {
				d.resolve();
			}
		});
	}
	return d.promise();
};

app.saveObj = function(obj) {
	$.when($.post(someURL,obj,function(data) { obj.id = data.id; }))
	.then(app.saveRows(obj))
	.then(app.renderObj(obj));
};

I don’t want to present this as though it’s super elegant or a magical solution. It’s actually more lines of code and, as far as I know, the stupid counters can’t be gotten around. Yeah, $.Deferred.resolve() is basically substituted for calling the callback. On the other hand, it seems much cleaner to me than the fake example, and you’re just going to have to trust me when I say that it’s worlds cleaner than the code I actually wrote. Mostly, it’s sustainable. The callbacks wait neatly chained for the event that indicates they should be called instead of being carried around through nested function call after nested function call (though the first example is condensed, that’s essentially what’s happening there – keeping the anonymous callback functions inline just makes it appear more connected).

I just fixed the front page of this site after a year, and added in deferreds to help manage some nasty bullshit with animations (not my strong suit) getting messed up if the animation function was called again before it had finished. I had two concurrent animations running each time I wanted to “flip a page”, and then they both had a couple of cleanup things they’d do upon completion. Now that list of final tasks happens only once both have run, and it’s out of the callbacks and nicely chained. It’s readable and consistent. As before, it’s not really solving a problem for me – the bug with the animations was related to a variable changing by the time the callbacks ran – but it makes for better code.

For me, the difficulty in understanding deferreds came in realizing that they aren’t magic. JavaScript only works this one way, so you still have to be able to think of your code in terms of, “I need this to happen and then I need something to trigger a different thing.” You have to map out the dependencies in your head or on paper and figure out the places where you need to wait. To me, nesting and passing callbacks has always felt conceptually like a lot of overlapping loops, loops that get paused part of the way through and then your app has several levels of functions waiting to move forward. I like deferreds because they make those feel more separate. Do this thing, and only once it’s done, begin this other thing. Under the hood I assume it’s still just passing around references to functions, but deferreds are a much easier way to think about this stuff.

So anyway. If you’ve also been waiting to grasp the nature of the problem deferreds magically solve to look into them them, you should stop. You should also stop nesting and passing around callbacks. It’s difficult to read, it’s difficult to manage, and it scales just like shit. I’m not really the best person to be talking about this, but I can say fairly confidently that deferreds offer an improvement. And, you know, maybe there is a magical solution somewhere in there that I just don’t know about yet. If you find one, you should tell me.

things that actually matter

May 8th, 2011

I had just gotten some very relevant facts about this and was about to update with corrections, when Alex Sexton posted his comment below. Please scroll down and read that before taking this without a giant grain of salt. I definitely jumped to some incorrect conclusions, and he’s got the real story down in the comment section.

I was really disappointed to see that jsconf is now the most recent “incident” on the geek feminism wiki. If you’re not familiar, that wiki collects things like sexual assaults and jokes about things being so simple even your mom could do it. That is, damaging and insulting shit. I may catch a lot of hell for this, but I didn’t find the presentation that happened during lunch on Monday at jsconf sexist. I assumed the guys presenting were trying to call attention to the lack of women at the conference in a humorous way. It definitely ended up being awkward, but my impression was that their hearts were in the right place. As for the thing about homeless transvestites, I admit I was only half paying attention, but I don’t think it’s unreasonable to simply mention homeless transvestites. Homeless transvestites exist. Anyway, someone explained later that the homeless transvestite thing was part of a botched anecdote about one of the presenters getting flashed, which had the potential to be a funny story.

However.. jsconf and nodeconf were the first two conferences where I’ve ever actually felt uncomfortable as a woman, and neither had anything to do with grade school humor onstage. This is why it fucking annoys me that what gets blown out of proportion on the internet is “OMG someone was mentioning women by name”. That’s not something anybody can do anything about now. If you saw the presenters afterward, it was pretty evident that they felt awful about it. I’d like to talk about shit that can actually be corrected, and I think it’s going to be a lot less well received than “don’t make jokes about how there aren’t enough women at this conference”.

“Are you a wife, or a girlfriend?”

Admittedly, I haven’t been to a whole ton of technical conferences. However, jsconf was the first I’ve ever been to where anyone assumed upon meeting me that I was there to do anything other than learn about tech shit. And – with apologies to any of the organizers or anyone else involved who may read this – I blame this on jsconf’s Significant Others Track. (Colloquially referred to as “the ladies”.) It was difficult for me to even purchase the ticket to my first serious technical conference because I was afraid I wasn’t qualified to be there, that I wasn’t good enough or smart enough. I don’t have any facts, but my guess is that a lot of women go through that, and it keeps a lot of women from ever attending a conference. But no one ever treated me as though I didn’t belong, until this week.

My impression was that the Significant Others were exclusively women (and babies), and that they outnumbered the women actually attending the conference. For me, this created a really upsetting dynamic where it was statistically correct to assume that any woman you saw hanging around the conference venue was not there as a developer. Good lord, it’s hard enough just mustering the confidence to attend these things. But generally, once you’re in the door, you’re safe. People know without asking why you’re there and there’s mutual respect among the attendees just for showing up. I shouldn’t have to wear a sign around my neck saying that I’ve been doing this for over a decade and paid a fucking grand to be there to be entitled to that default level of respect, to not be assumed to be there merely as arm candy. Filling a conference with women who are not developers makes it that much fucking harder to be a female developer at that conference.

I told a friend how I felt about this and she pointed out that the SO track makes jsconf more family friendly, and allows men who might not otherwise be able to attend to come to the conference without leaving their wives/kids/girlfriends behind. My opinion is that if you want to be family friendly there are better ways to accomplish that. If you just want men to be able to bring their families, nothing fucking prevents them from doing that at any other conference. Their SOs can still go tour all over the city while they do their important man stuff, assuming they’re homemakers or otherwise in the position to take a week off to go chasing after their man while he pursues his professional interests.

I was really not trying to hate on the SO track but, bluntly, I do hate it. I hate that there’s a special place for women at this conference and it’s not in the seats watching the presentations. I hate that, as many times as I’ve had to jump the fence between what a woman is supposed to be doing and what I personally want to be doing, I come this much closer to my goal – as far as where I want to be and the kind of developer I want to be – to find that same fence erected again where I least expected it. I hate that the comfort and community involvement of wives and girlfriends is more important than the comfort and involvement of female developers because we are outnumbered. But I’ll try to quit ranting and actually say something productive.

the perfect couples’ getaway

Rather than offer free SO track tickets, it would be super cool if jsconf/nodeconf offered discounted tickets to the actual conference for significant others whose partners had already purchased regular price tickets. Don’t think anyone would use them? Maybe not, but then what the fuck are they doing at a JavaScript conference? You want a family vacation, take a fucking family vacation. You want to interact with the JavaScript community, go and fucking do that. If you want your girlfriend to interact with the JavaScript community, buy her a fucking ticket. I did actually meet someone on the SO track who was interested in front-end dev, so there. She was already a developer, just not working with JS. While I’m sure there were plenty of women on the SO track with no interest in dev, I’m betting there was more than one with the aptitude and motivation to have actually gotten something out of the conference itself.

In a pretend world where something like this would exist, it would be really awesome. Yeah, any woman who took advantage of it would have to get over the whole arm candy stigma, but it’s a lot easier to go to a conference if you know someone there. If that someone has to be a husband or a boyfriend, it’s better than nothing. We need more female developers so we don’t keep losing female developers due to the lack of female developers. As far as I’m concerned, anything that gets ‘em in the door is rad.

what about the children

I had a really interesting conversation with a friend at jsconf about getting kids into development. I had another conversation with another friend about how daycare would be a lot more inclusive than an SO track. At some point these ideas merged and I began wondering why jsconf doesn’t have a kids track. There were certainly plenty of kids there. I guess you’re probably not supposed to take your kids out of school for a week so they can go to a JavaScript conference, but what if you could? What if young kids were learning how to make a simple webpage while their folks were learning about collision detection and unit testing? What if single parents could attend as easily as dudes with wives? What if people could trade a couple hours watching babies or teaching kids for a free jsconf ticket? I think that would be fucking awesome.

I guess this goes back to the big thing I don’t understand, which is why, if jsconf is supposed to be a family event, there aren’t family JavaScript activities. With the amount of talent present and given that offspring of developers are going to grow up around development anyway, it seems like a natural place to teach kids fun, simple development shit. It’d be like the best bring-your-kid-to-work-day ever.

the ladies’ room is called that for a reason

Nodeconf was a complete sausagefest, but I don’t want to pick on them too much. As far as I know, there are no famous women within that community. There weren’t any female speakers. With no female role models, you’re just not going to see many women getting involved. The ground has yet to truly be broken there, but that’s not the organizers’ faults. (Ahem. Ladies.) However, there was one fairly wrong thing that happened. To their credit, it was corrected almost immediately, but it still kind of blows my mind it even happened in the first place.

Developers – male and female – can sometimes be more logical than is healthy, and I assume that it was in the name of efficiency that the women’s bathroom was relabeled a unisex bathroom, with a single stall reserved for ladies only. Like I said, I think the sign was gone before the first talk had ended, but it’s important to know why this was uncool. There were totally way more men than the men’s room could accommodate and so few women in attendance that I only saw another person in the ladies’ room once. But the ladies’ room is the one thing that’s ours by default. We had to fight to be taken seriously as developers, fight to get good jobs and interesting projects, fight to overcome the fear that we’re not good enough.. we shouldn’t have to fight for a bathroom without boy-pee on the floors. I feel like seeking out more diverse participants is an endeavor best left to more mature communities than node’s. But that doesn’t mean you can reclaim resources already dedicated to diverse participants if you don’t see enough people using them. It’s always good to keep a women’s bathroom around and work toward the day when there’s a line out the door.

I am so tired of talking about this

Something you might not know about me: I write approximately one women in technology blog post per month. I usually don’t publish them. I get angry and then, by the time I’m halfway through writing, I’m sick of it. This one is going to make it cause I think the stuff about the significant others needs to be said and I don’t think anyone else agrees with me and is going to say it. The bathrooms thing shouldn’t need to be said, but apparently folks need a reminder sometimes.

There was one thing about the lunchtime presentation at jsconf that bugged me. It wasn’t the things being said, but the way they were said. It felt as if the presenters didn’t think of the women at the conference as their peers, as being exactly like them in every way but their sex. I’m scared to talk about this stuff. I’m scared to isolate myself, to always be part of some exclusive third party my male peers have to tiptoe around when mentioning us. I would rather be down in the mud listening to dick jokes and #twss than be part of a group that’s on some pedestal where no one can talk about us or to us without complete political correctness and unfailing reverence.

I think with a slight shift, the lunchtime presentation could have been fucking hilarious (while also a little tragic). If they’d brought up a close female friend they knew they could fuck around with instead of a guy as their first “guest”, there could have been some very funny teasing of the giant elephant in the room. I think. It made me wonder if those guys knew any of the female developers there well enough to fuck around with them on stage. The change in tone when they finally did bring a woman up made me feel like maybe not, or maybe they did know her well enough for that but were worried about what the audience would think.

I no longer think the scrutiny we apply to this issue is healthy. I’m actually having doubts about the All-Girl Hack Night, based on this week. I’m tremendously worried about mentioning the bathroom thing outside of an intentionally-not-hashtagged tweet, lest that too fucking end up on the geek feminism wiki. We need to be able to talk about this shit without fear of repercussion. That means men, too. We need to be able to make jokes about it. We need to do this so we can stop fucking discussing it.

keyboards

April 4th, 2011

When I was in college, I worked in the computer lab. One of the very first things they told us during training is perhaps the best thing I’ve ever learned in my entire career working with computers: never touch someone else’s keyboard. It doesn’t matter if the keyboard involved is actually yours, and someone else is just sitting in front of it. You don’t touch it. This is a pretty good metaphor for anything that has to do with helping someone else solve a problem, even problems that don’t involve physical keyboards.

What they wanted us to avoid was something that’s sadly common among geeks – the tendency to push the other person out of the way and say, “Nevermind, I’ll fix it.” Maybe we sometimes think it’s more efficient if we just fix whatever the issue is. In that moment, we’re probably right. But that momentary efficiency creates long-term inefficiency by breeding helpless users, colleagues, clients, whoever. It’s also a total dick move.

I’m not going to say anything about the relative merits of teaching dudes to fish vs. giving them fish. We all know that. This is a post about the dick move part of the equation, and how that’s a big fucking problem among computer geeks to this day.

There’s always been this incredibly stupid yet romanticized picture of computer people living in basements, working in isolation, and getting things done the Good Old American Way, with no help from anyone. There’s been a tendency to treat developers and sysadmins and various types of geeks as heroes when they stay up all night and finally fix something (that probably wouldn’t have been broken if maybe they weren’t the only people working on the problem to begin with). There’s been a disincentive to collaborate and a territoriality that appears a hell of a lot like it’s driven by the fear that omg someone else may be better at something. And it’s all a bunch of stupid, useless bullshit. We know people, geeks or not, do better when they collaborate, when they aren’t afraid to be wrong, and when their egos take a backseat to their work.

What does that have to do with not grabbing the keyboard? Everything. Grabbing someone else’s keyboard is a physical and therefore very obvious way of demonstrating superiority. It implies not only that you know something the other person is ignorant of, but that your time is too damned valuable to waste it explaining it to them. It’s a lot like being that jackass who always has to shout out the answer to a question first and loudest before anyone else gets a chance to respond. Same goes for any time you don’t help someone understand the solution to a problem but instead take it upon yourself to fix it, whether or not input devices are involved.

I don’t spend a lot of time lately helping people save their files in Word. Mostly I spend my time working on code. And while this shit is annoying and rude when it’s explaining word processors, it’s downright fucking dangerous when it’s the codebase of a live product. If you’re a keyboard-grabber, maybe you think the joke’s on me. Maybe you think you’ve found an awesome way to ensure you’re always the most valuable person on your dev team by hoarding as much knowledge as you can. Maybe you think the long hours and late nights you spend fixing things you could have delegated are worth it. Hell, maybe you even think that because you’re the one who always gets shit done, you’re completely fucking awesome.

Well, you’re not. You’re being a total pain in the ass.

I’ve never been a keyboard-grabber. Don’t mistake that for horn-tooting, I go the opposite direction to a definite fault. I’m ashamed to contemplate how many hours I’ve wasted trying to force business people who just wanted to change the pictures on their websites to learn CSS instead of using HTML attributes because “this is better!” Being this way means that when I encounter keyboard-grabbers who I have to work with, I have a difficult time not trying to drag them to some kind of middle ground. Well, that’s a lie. I don’t try not to. I jump in there all, “Motherfuckers we are going to COLLABORATE. RIGHT NOW.” But whatever. In this case it’s worked out and what I was gonna say was how and why.

I think not fixing problems in isolation is scary for people who are used to being cowboys. For one, it spreads the value of your knowledge around, diluting the value of your personal stockpile. For another, you can’t control the outcome, and there’s the possibility that you may have to suffer through someone else not getting it for weeks or months, when you could have fixed the problem in a couple hours. But mostly I think it may be scary because you’re changing what you know works for you, and the value isn’t apparent. I don’t mean the value to the team, which I shouldn’t have to explain the immenseness of. I mean the value to you, professionally.

Somebody smart wrote somewhere that you should always try to be the dumbest person in the room. Being the smartest person in the room sounds good on paper, but the smartest person in the room isn’t getting any smarter, they’re just standing around looking pretty. The dumbest person in the room is learning shit without even having to open their mouth. When they do open their mouth, they can ask questions and not care if they make them sound dumb, because asking dumb questions is what the dumbest person in the room is supposed to do. If you set yourself up as the person with all the answers, who has to fix whatever’s broken and bless whatever’s imagined, you don’t get to ask any dumb questions. If nobody ever gets to be smarter than you, you never get any smarter. You can read shit on the internet and make little side projects with flavor of the month technologies, but unless someone’s actively challenging your assumptions, you’re learning less than you could be.

When you stop grabbing people’s keyboards and explain things to them so they learn it for themselves, you create intellectual antagonists. You give them the opportunity to be like, “But wait isn’t Way X bad and isn’t Way Z more performant,” and then you’re all, “What? Dude no Way X is The One True Way STFU and copy that thing over to there,” and then secretly you look it up and it turns out Way Z is totally better than Way X for some completely different reason and OMG THAT N00B JUST BLEW BOTH YOUR MINDS. This is absolutely the best thing ever.

I’ve been lucky enough to see a few hierarchies of smartness completely fall apart. It’s always really obvious when this happens, because beforehand everyone is just glaring at each other not saying anything and afterward nobody can fucking shut up about node.js or OOCSS or closures or whatever. You also get something that may seem anti-collaborative: healthy competition. You’re not waiting for one dude in suspenders and long, flowing robes to update your company blog, you’re all racing each other to push stuff to github and then filing issues and making pull requests and generally knocking each other’s egos down daily while also having a really fucking good time. Maybe that’s not how it always plays out exactly, but you get what I mean.

I said how and why, and that was the why, I guess. The how is shorter: stop grabbing people’s fucking keyboards.

too much jquery.. ?

January 30th, 2011

This weekend I tried to take part in a virtual MDN documentation sprint. I say tried because, while I was present in IRC for some part of it and submitted some updates, I don’t think I got a lot done. I changed a couple things that had been bugging me about the Rich-Text Editing in Mozilla page, but it turns out that more accurate information had existed the whole time on a different page, so that didn’t really add a lot. Having finished that one little thing and feeling not very helpful, I went in search of something else to do and saw an item on the sprint wishlist about updating the Getting Started with AJAX page. I was like, “Sweet, this is easy stuff, I can do that!”

HA.

I cannot, as it turns out, do that. Not without many hours of research. I used to be able to do that, but now I do this: $.ajax(...); I do it too much. I do it so much, in fact, that I no longer have any idea what current versions of browsers actually require to complete a successful XHR.

I’m not a jQuery hater – far from it. I use the shit out of some jQuery, I’m always trying to fix the ways I use it incorrectly, and I think it’s extremely handy. Initially I was no fan of it, but at that point I was categorically against any sort of JavaScript library. Once I started using it, I came to appreciate it very quickly, and once I began to appreciate it.. Well, that’s how we get to now, where apparently I can’t write fucking JavaScript anymore.

I realize I’m hardly the first person to be concerned about reliance on abstractions preventing front-end developers from having a solid grasp of JavaScript, but – pardon me, cause this is douchey – I didn’t think that applied to me. Having once had that solid grasp and having applied that knowledge on the daily for a few years, it just never occurred to me that I would lose it if I didn’t use it. I thought the people to be worried about were those who were new to JavaScript and, having started out with libraries, never learned the fundamental concepts. It’s now much more clear to me how stupid that was. Browsers change all the time (well, most of them). To believe that the correct way of writing JavaScript in 2008 is still the correct way to do it in 2011 is just ridiculous.

For example: when I was trying to update that AJAX document, one of the first things I did was to remove the word “nonstandard” as an adjective describing XMLHttpRequest. That took about half an hour. I was pretty sure it was standard, but I’d never really checked. I still don’t really know. The W3C has a document on it, but it’s marked “Candidate Recommendation”. Does that make it standard? Does the fact that modern browsers have implemented it in a standard way make it standard? Is it not standard until all the browser-specific caveats have been removed from the implementations? Not only was I unfamiliar with the state of those caveats, I didn’t really know the disposition of XHR as a standardized concept, and still am not 100% confident in my research on the subject.

And dude, that is sad. I extol the virtues of XHRs at work constantly, in every planning meeting, in every design session. I’m like one of those people on twitter who talks about how awesome Justin Bieber is even though they’ve never met him. I am a creepy XHR stalker/fan who’s based her devotion on an impression that leaves out much of the detail. No one who likes to present herself as a professional front-end developer should be doing that.

So, having realized this, what do I do about it? This is the rub. Probably the best way to maintain a good understanding of JavaScript is to be a library author. I don’t mean add another publicly released library to the slew of excellent ones already available, but write internal libraries, creating the same abstractions that I’d normally depend on jQuery or any other library to provide. But that’s a little ridiculous. I do write a lot of my own widgets, but that’s just because I don’t want all the options and config stuff that come with a big, complex, do-everything plugin someone else wrote. Abstractions like jQuery’s ajax() are more universal, because they simply wrap a standard* up in a shorter function call. It’s good that people can rely on that stuff being in the libraries they use and that that knowledge is useful across a variety of projects. It’s probably pretty dumb to create a new XHR abstraction for each new application one works on.

Maybe it’s obvious that I’m not sure what to do about my JavaScript knowledge getting stale. I’m not into doing things just to prove I can, but in this case, I’m not sure what would be a better approach. Part of me thinks there may not even be a benefit to staying current on the implementations of common, slightly mundane things like writing out an XHR long-hand. I don’t know anyone (aside from library authors, who I only know of) who does their work in plain ol’ JavaScript. I like to believe we’re moving back to that, though. I always picture jQuery et al as projects that exist to hasten their own obsolescence. Maybe that’s crazy and, as someone who merely implements this stuff, I should just embrace the fact that I’m losing the right to call myself a JavaScript developer in exchange for the security of not constantly reinventing the wheel.