Thursday, October 17, 2013

Digital Learning Apps in Guatemala

In between the talks and workshops that I gave at FIT this week, I also got the chance to talk to many people that are involved in digital and online learning in Guatemala, and was surprised to find out the many ways they're experimenting in the space. I want to highlight two projects here:

Telescopio

This is Galileo University's take on the MOOC format, and is led by GES director Rocael Hernandez. They developed the web app in house, culling together open source projects and APIs into a platform that supports lectures, quizzes, discussions, and peer assessments. They started it off with an iPhone courseand based off the Stanford iPhone course curriculum, and now have 6 engineering courses on it, with 2-5,000 spanish speaking students enrolled in each. They've experimented with various aspects of the platform, like using the Google Docs API to track changes to a document, and have published a few papers in the space: MOOC in Latin America, Implementation of Online course with Accessibility features, MOOCs Concept and Design using Cloud-based Tools.

Cerebrex

This project was initiated by their Education Innovation director Ali Lemus, and is an experiment in finding a new way to teach math and reasoning to young kids. Cerebrex is a game made for Android, iOS, and the web that presents challenges in a Maya-themed setting, translated into the Mayan language of the user (there are something like 30 spoken Maya languages in Guatemala). They trialed it in several classrooms, and saw great results with increased intelligence measurements after the test. Ali told me the story of one student that was young for their grade and bullied for that, but once that student was at the top of the game leaderboard, their classmates suddenly respected them. That's an anecdote, of course, but its promising, especially in a country where students have low confidence about their place in the world to start with (or so I'm told). Ali shared his slides about Cerebrex here.

It's easy to think that it's only Silicon Valley where innovation happens, but really, whenever I visit another country or talk to a foreigner, I find out about the amazing projects that they're working on in the education space, and realize that of course, we're not the only ones. It sounds obvious, typing that now, but it's nice to venture outside and get a reminder of this every so often.

I look forward to seeing what Guatemala does in the education space in the future!

Tuesday, October 15, 2013

1 Day in Antigua, Guatemala: Where to Go, What to Eat

At the end of my trip to Guatemala to speak and teach at the FIT conference, our gracious hosts took us on a day trip to Antigua. Antigua was the second capital of Guatemala, 12-by-12 blocks of colonial architecture and Baroque style cathedrals and churches. After it suffered from an earthquake in the 1700s and many of its structures went to pieces, the capital moved to Guatemala City, where it is now. Antigua is a popular destination for tourists, who can walk amongst the ruined cathedrals and enjoy local food. If you ever get the chance to visit it, here's what I recommend.

Where to go

  • 2013-10-12 at 10.32.53 El Tenedor del Cerro: This little collection of museums and restaurants sits atop a hill, where you can see three of the volcanoes that surround Antigua (2 active ones!). As you walk around and enjoy the mosaic murals and sculptures, parrots from their sanctuary will happily land on your shoulder and tweet away.
  • Cerro de la cruz: Before venturing into Antigua, drive up for a view from the cross. You'll get another vista of the volcanoes (a straight on view of "Agua", if there are no clouds) and a birds-eye view of Antigua. You can also see the first capital of Guatemala from there, if you squint and look for the white church near the base of the volcano.
  • 2013-10-12 at 12.54.36 Las Ruinas: You can wander around giant blocks of cathedral, now the home for beautiful sprouting flowers, and wonder how magnificent they once were, back when the cathedral actually had a roof. Or, if you're like me, you can count the number of times an enamored visitor has proclaimed their love by etching it into the walls, and wonder how many of them actually stayed together.
  • Sereno: A restaurant that doubles as a popular spot for wedding ceremonies, thanks to a rock-studded cave that looks beautiful inside when lit up by tiny white lights.
  • 2013-10-12 at 15.36.10 Hotel Museo Casa Santo Domingo: Another popular spot for weddings, home to an open air cathedral surrounded by ruins. They cover the fountains and grounds with hundreds of candles each night, and if it's a wedding night, *thousands* of candles, which I was lucky enough to witness. The grounds is also home to rather noisy parrots and a chocolate shop.

What to eat:

  • Dulces tipicos: Translated literally, they're the "typical sweets", and they're candies and pastries that are part of the Guatemalan tradition. You will need to pace yourself to try all twenty-something of them, or pick and choose - I tried the sweet coconut bar (a bit too sweet for me), the coconut macaroon (yum, just right), and a macaron-like almond cookie (also yum).
  • 2013-10-12 at 13.13.53Chocolate: Guatemala is home to many chocolate and coffee farms, so you'll find multiple local chocolate shops while walking around Antigua. In fact, you may want to skip eating normals meals and just stick to sampling chocolates. You can try different exotic mix-ins at ChocoLala, like chocolates with rum, ginger, or papaya, or go for more classic chocolate at Guatemala Chocolates, or even go for a chocolate-making class at ChocoMuseo.
  • Steak: You can eat steak the Guatemalan way at Casa Santo Domingo - with guacamole (no tomatoes!), frijoles volteados (bean puree), salsa, and platanos. You'll have to enjoy it with a red wine from Chile, not Guatemala, because it's too hot for them to make local wine, but hey, the Chile wine is highly enjoyable.
  • Ron Zacapa: The native rum of Guatemala, you can drink this straight (if you're into that) or mixed with Sprite and ice. Once you do, you'll likely find yourself buying a liter to bring home for your friends to try. Or you'll just find yourself drunk.

Disfruta-te de Guate!

*I wrote this after reading United Airlines "Hemispheres" during take-off, so, uh, if this sounds too much like an airplane magazine article, blame the fact that I can't use electronic devices on airplanes during take-off.

Monday, October 14, 2013

Shyness Hacks for Conferences

Update: I've now moved these tips and more into a dedicated site, ProjectIcebreak.com.

A few years ago, I gave an ignite talk at Google I/O about the ways I'm shy and the many ways I've found to work around my shyness. I recently saw a post on overcoming shyness at conferences on HN, and realized I never formally wrote up my own tips.
Before going into my shyness hacks for conferences, let me clarify what I mean when I say that "I'm shy". For me, it means that I'm afraid of approaching and talking to people, especially when its me and a group of strangers. Ultimately, it's because I'm afraid of rejection. As long as I don't approach people, then I don't have to worry that they will ignore me or turn me away. Sometimes I try to just be a hermit and not worry about my fears, but I soon realize I crave human interaction, and always will. If I'm going to go through the effort to go to a conference, then I don't want to waste that opportunity for interaction.
Given that, here are my shyness hacks for conferences:

Be a Speaker

This is my primary hack. I will almost never attend a conference if I'm not a speaker, because I know that if I'm just there as an attendee, I will spend my time getting shyer and shyer until eventually I'm just reading my book in a corner in the bathroom.
After I deliver a talk to a group of people, there will be a whole room of people afterwards who know who I am and even better, who know what conversation topics they can approach me with. Speaking isn't easy- I still get sick to my stomach just before I talk- but for me, its worth it. When I moved to Sydney and didn't know anyone, I gave two talks at their BarCamp my first weekend there, and that's how I met 90% of my Aussie friends. If you're nervous about speaking in front of a big audience, start small - give a lightning talk or lead a BOF session - that's still a group of people that now know who you are!
Whenever I get the choice of when to speak in an event, I always ask for an early slot - - early in the week if it's a multi-day conference or before lunch if it's one day. I want to make sure that people know who I am as soon as possible so that I can spend the rest of the time hopefully getting approached by them with their thoughts on my talk.

Talk to Speakers

Okay, let's say you really don't want to be a speaker, or you didn't have a speaking opportunity at this conference. Now that you've seen that many speakers (okay, at least one of us) become speakers because they want to be approached, an obvious hack is to talk to the speakers.
I will typically keep a running notepad with the questions that come to my mind during a talk, and then I will often ask one during the formal Q&A, so that the speaker's seen my interest, and save the rest for attacking them after with my curiosity. Most of the time, the speaker is more than happy to answer questions, and loves that somebody is interested enough to ask.

Go to Workshops

Traditional presentations are not very conducive to social interactions. It's a bunch of people, watching a speaker, and the only opportunities to talk to each other are before and after. A workshop, however, is inherently more interactive: there's many a time at which you'll be working on an exercise, and that's a time at which you can talk to the people near you about what you're working on. If you want to be very popular, then try to be the one that pays a lot of attention and can help out everyone else. Otherwise, don't be afraid to ask for help, too. (Just not *too* much).

Be a Conversation Piece

This is a hack that works anywhere in life - parties, cafes, dinners. If I make it so that some aspect of my physical presence provokes conversation ideas, then people will have an obvious and immediate excuse to talk to me.
That's typically in the form of a t-shirt, like a geeky one, an awesome band, or some ironic one from Threadless, but it can also be in the form of a crazy hat or accessory, like my often brightly colored hair or super cute animal socks. I actually don't wear geek t-shirts to work anymore, but I've saved up a spectrum of them so I have appropriate ones to wear at each conference I go to.

Hand out Free Shit

This is the hack that I used as a kid. I was shy around my classmates, so I would bring crazy candy to school in a Santa-like bag and offer it to everyone around me. The word would get around fast, and pretty soon, everyone would be approaching me, even the "cool" kids.
This isn't something I've done frequently myself at conferences, but I've seen others do it. Lug around a bag of cool stickers or shirts, and pretty soon, because we all have grade school sticker-mongers deep inside us, you'll have random strangers approaching you for them.

I'll update this as I think of more. Feel free to share your own hacks in the comments!

Tuesday, September 24, 2013

On the Arbitrariness of Swear Words

The setting: my third grade classroom.
Our teacher was walking around the room slowly, armed with a pile of freshly graded quizzes. She came to my desk and laid down my quiz - face down, of course, so that I'd have the chance to review my grade before casually laying it face-up for bypassers to "ooh" and "aah." I turned over the quiz expecting an A, like the cocky 3rd grader I was, and lo and behold, I discovered a "B+" written in vicious red.
I was appalled at myself. Sure, I had the occasional A-, I was fine with that, but I was an A student, not a B student. How'd I let this happen?
"DAMN IT!", I yelled, in my frustration, at nobody in particular, at myself more than anyone. At least that relieved a little bit of my tension.
Our teacher whipped around, raised her finger in the direction of the door, and issued a stern "Wait for me outside."
What? What was this? Was she also as disappointed in my grade as I was? Is this what happens to all B+ students?
I was perplexed. I really had no idea why she'd sent me outside. You, as an astute reader well versed in the ways of the Western world, you likely figured it out. But I, the unaware third grader, just feeling my way in the world, I just couldn't figure it out.
She finally came outside, and I prepared for an explanation that would clear up everything.
"We don't use that word in the classroom!"
"What word??"
"That word that you yelled."
"Why not?"
"It's a swear word!"
"What's a swear word?"
Suffice to say, she was not very happy with me at this point. I was generally a good, obedient student, and suddenly, I was challenging her at every turn.
But I was just being honest. I didn't know that there were words called "swear words", that there was such a thing as "swearing."
You see, my parents were scientists - British scientists, to be specific - and they never got in their heads to teach us the basics of American manners. Thinking back, I can remember only two times that my dad scolded me for the words I used:
  • When I called my sister a "bitch", loud enough that the whole house could hear. He didn't care whether "bitch" was designated as a swear word, he just cared that I was saying a rather mean thing. That was fair. (Though she probably did something unforgivable like steal my candy).
  • When I answered questions with "yeah." He said that was "unfinished" and "non-committal" and every answer I gave should end in a real sound, like "yes" or even "yep". Yeah...so that lesson never stuck, though I did say "yesh" as my standard reply for a long time, to get around it while still avoiding conformance to boring old "yes". I was such a rebel, aye?
At this point, I'd started to wrap my head around the idea that there was an arbitrary set of words designated as "swear words", but what was in that set? How would I know to avoid them if I didn't know what they were? I could try to ask my parents, but they might just muddle my mind with their British-isms instead. My teacher was not forthcoming with them, but thankfully, my peers were happy to supply a list. And what an expressive list it was!
From then on, I knew not to scream profanities in front of teachers, but I also always had a sense with me or the arbitrariness of swear words. I could never quite take someone seriously when they put effort into scolding about swear words, because I never quite believed there was anything inherently detestable about them. These days, I try not to *over*-use them, but I definitely use them. I use them to get out my frustrations, to express to others the magnitude of my emotions around something, to add impact to a message.
As a linguistic aside: swear words serve a unique function in the English language - "fucking" (or if you're British, "bloody") is one of the only examples of a linguistic phenomenon called "infixation". It means we can infix it in words, like "abso-fucking-lutely", and our brains parse that as perfect English, and there are specific rules that dictate what syllables can be infixed. I know this because we covered it *twice* in the course of my linguistics minor, though my second professor was so reserved that she couldn't bring herself to use the American example. It amused me to see that even a linguist could feel bound by societal rules to not swear.
There's a part of me that wonders if we enforce "no swearing" with kids and in formal settings purely so that we can further enhance the effect of swear words when we use them ourselves. If we never hushed a kid yelling "damn", would we get as much satisfaction from yelling it ourselves? I don't know, but I bet there are linguists and neuroscientists out there that have done all sorts of interesting research on how swear words form, how they change over time, and what effects they have on the brain. (If I wasn't writing this on the train, I would look it up myself, but I will instead leave it as an exercise to the reader).
Back to practical matters: now that I'm working on the programming curriculum for Khan Academy and teaching kids in person, I need to make sure that my lessons and comments are all kid friendly, mother approved. I have no desire to spark a debate with an angry parent on the exposure of kids to swear words, as I don't want to distract from the point: learning programming.
That means that I find myself trying to swear less, or find substitutes for swear words that are just as satisfying and effective. I've already found a few from the community, like the oh-so-visual "Oh My Fried Chicken!", but I have yet to incorporate them into my every day speech. I have to re-train myself to avoid the words that come reflexively to me, the words that are used so heavily by the adults around me, the words that feel so damn good to say. That seems... hard.
But garsh darn it, I'll give it a go… and check back in 10 years to see what the next generation thinks about swearing.

Saturday, September 21, 2013

JSConf 2013: My Favorite Talks

I was fortunate to attend JSConf 2013 this year. I was a speaker in their training track, where I had fun giving a workshop on Backbone. Shout out to HackReactor teachers Marcus and Tony for being my super helpful TAs.

When I wasn't workshopping, I got to enjoy some amazing talks from a wide array of speakers. They're now all available online, so here's a list of my favorites:

  • Nicole Sullivan: Creating Living Style Guides: Nicole explained how she worked with Trulia to refactor their CSS, work out performance issues, and create a style guide. You'll come away wanting to have a style guide for your site, if you don't yet. Khan Academy has a basic one here, and even though it doesn't cover everything, it's already helped me to avoid making up new styles.
  • Rebecca Murphey: Optimizing for Developer Delight: A talk on engineering team culture, communication, tools, documentation, and best practices. A great one to watch particularly if you're a tech lead or manager.
  • Angelina Fabbro: JavaScript Masterclass: A talk that's more about becoming a better developer and approach to learning than about JavaScript itself. I love her philosophy so much.
  • Seb Lee-Delisle: CreativeJS - making art in the browser: Seb couldn't attend because of Visa issues, but he made it work over remote video. And yeah, normally you'd think a remote talk at a conference would be horrible, but it was amazing. Since he couldn't hear us for whatever reason, he made us wave his hands to show our applause or laughter or agreement, and that made it more interactive than the in-person talks. And Seb was generally awe-inspiring with his ability to make creative programming look easy.

Saturday, September 14, 2013

Technical Interviews Make Me Cry

First, let me clarify one thing for those of you who've never dated me: I cry. A lot.

When I can't get my vagrant box setup correctly after 3 hours? Crying.
When I use an MVC framework for the first time in my life and I'm banging my head against it? Crying.

So, yes, on the spectrum of manly-man-no-emotions to chronic crybaby, I'm very much to the right. Above average, you might say.

Now, back to technical interviews. I've been lucky to have very few in my life, because I'm kind of a love-at-first-sight girl when it comes to jobs. There are very few job descriptions that I've read and fallen in love with, so when I do pursue them, it usually turns out well because it aligns so well with my particular skills and interests.

When I applied to Google, I went through a brief phone screen with an array of short questions (which were easy enough since I was still in the thick of my Computer Science major), a take-home worksheet with fun challenges, and an in-person interview which was mostly me talking about my favorite projects, with a few classic questions that I'd prepared for, like reversing linked lists

When it came to Coursera, I didn't actually apply. I thought I was just going to the office to meet the team and chat about our shared interests. But then they said "well, actually, we'd like for you to join us, and for this to be an interview." I freaked out, because, hey, I had not prepared for an interview — and I hadn't done one since that Google process 5 years before. But, maybe I could use that as an excuse. My first interviewer eased me into it gently and probably because of that, I managed to make it through the rest of them with a smile on my face. I still think they took it easy on me that day, because man, I've seen the interview questions that they gave to candidates that came after me, and I can't see myself making it through those with any degree of confidence.

A few months ago, I decided that I really wanted to join Khan Academy. I would longingly browse their jobs page in my idle hours, read their intern blog posts from top-to-bottom, and fork their repos on Friday nights. It became a bit of an obsession. (Shh, don't tell them how creepy I am.)

The interview process was scheduled to begin as most do: a 40 minute phone screen with one of the engineers. I wasn't sure how to prepare for it, what sort of questions I'd be asked. I figured I'm known for more frontend work these days and folks may be under the misguided illusion that I'm a JS expert, so I read through parts of the ECMAscript spec, reviewed the craziness of prototypal inheritance in JS, and read through all the frontend posts on that engineer's blog. Part of me thought I should study more, study enough that I'd feel confident that I could handle *anything* they threw of me, but that would have taken me months, if that. More likely, I'd never feel 100% confident.

When the time came, I sat there on my bed, on an unusually hot San Francisco day, and dialed into the Skype call. My interviewer started with the usual, asking me about a recent project I'd worked on, and I randomly selected something that was hopefully remotely interesting. Then, we opened a Stypi and he gave me the coding question. I won't say exactly what it was (in case that's his go-to question), but it was basically figuring out how to calculate some bit of data, nothing language specific, more math and logic.

And that's when I froze. I didn't immediately know how to answer the question, and I broke down.

I stared at the wall for minutes. I listened to my interviewer breathing, knowing that he wanted me to start working through the problem, but at that point, I couldn't.

The only thing going through my mind was "I can't do this."

I stared at the "hang up" button on Skype. I could just press it, and he would go away, and then I'd give up on my obsession, and I would convince myself it was a stupid idea in the first place.

I could feel my palms getting sweatier, and then I could feel the tears start to come. And the silence grew more uncomfortable. It'd been minutes since I said anything. I needed to do something, anything.

I finally managed to convince myself that I'd be an idiot for hanging up, and in an act of honesty, I choked out something like, "Um, I'm sorry, I've literally gone blank and not thought about anything for 5 minutes. I'm not used to coding on the phone."

And my interviewer understood. He guided me through it, urging me to keep going, even though I kept wanting to throw in the towel. I wanted him to give up on me, to realize the mistake I'd made in thinking I could meet their bar, to put me out of my misery. At some points, I couldn't type because I could no longer see through the tears that had welled up in my eyes. But eventually, we got to the end of it, and the interview was over.

And then the sobbing REALLY began. I had just finished the first step of the interview process with the company I desperately wanted to work for, and I'd bombed it. I’d frozen, I’d cried, I’d stumbled through my somewhat shoddy solution. Did I really deserve to even be an engineer, if I couldn't even make it through a phone screen? What gives me the rights to give talks at conferences, if I can't make it through standard interview processes? I was pretty damn frustrated with myself.

After a night spent in existential crisis mode, I found out that I'd made it to the next step. Apparently, my solution wasn't that shoddy after all and somehow, I hadn't scared my interviewer off.

It was then that I realized the most important part of prepping for the phone screens: confidence. Even if I didn't really have any, I had to convince myself that I did, and do everything in my power to not mentally run away. By the last phone screen, I was almost having fun.

This story has a happy ending: after three phone screens, a fun take-home assignment that literally had me bouncing off the walls in excitement, and a chat with the team, I was offered the job and have been working there ever since.

What are the take-aways from this?

If you're an interviewee: don't just prepare for the material, prepare for the format. If I had made myself go through the uncommon and uncomfortable situation of being put in the spot and asked to answer a random technical question, maybe I would not have cracked so easily when it came to the real deal. If you ever suffer from Impostor syndrome, you should probably prepare even more, because the standard interview situation will make you feel like an Imposter in the worst way.

If you're an interviewer: seriously consider the format of the on-the-spot technical interview and whether that's the best way to judge all candidates. In my experience, when we are programming on the job, we're given the problem and we have time to think about it. We have time to research possible solutions, we have time to try stuff out that we know will most likely fail, and we can wait until we have something decent before we show it to our colleagues. Oh, and as it turns out, I don't actually cry much at work - maybe a few times a year, when I'm already having a horrible day and I'm struggling against something that just won't work.

That's why I love the format of the take-home assignment. Both times that I've been given one (Google and Khan Academy), I loved them both because I had the time to really sink my teeth into them and because I got to experience what it would be like to work in that role. The take-home assignments were always very similar to actual work projects, so by doing them, I could figure out whether I'd actually be any good at it, and whether I'd like doing it. That's valuable for the interviewer *and* the interviewee. Yes, it’s hard to judge an assignment when you can’t witness its process, but it’s a surmountable task.

Now, I know that not everyone likes take-home assignments - and I know that some engineers absolutely love interviews, or at least prefer them to a take-home. So, I’ll stop here before this post becomes a 10-page exploration of alternative interview practices. Maybe that will be a future post, once I start being an interviewer again. Apparently Khan is keen to keep experimenting with more take-homes. :)

But just take this away then: remember that an on-the-spot interview can be incredibly intimidating and frightening for some people. Try to remember what it can be like to be in their situation. Ease them into it. Be understanding. And forgive them if they cry.

Thursday, August 22, 2013

Communication at Khan Academy: Open By Default

I've only been at Khan Academy a few weeks now, and I'm still learning how they (we) work as a company and what makes their (our) culture tick. But, there's one thing that I can't help but notice: our communication is open by default.

I don't know how much of the openness was a conscious effort and how much was coincidence, but at this point, it's a definite part of the culture now. Here's where I've seen it:

  • Public Wiki: Khan has a Google Sites wiki, and it is actually openly viewable to anyone. Newly created pages are public by default, but can be made organization-restricted if it contains secret information. I almost thought it was a mistake at first, an accident, but it's very much on purpose. Khan works with many external volunteers, and it makes it easier if we can easily expose documentation about best practices and processes on the same wiki that we use for employees. There's a fine line between "internal" and "external" at Khan, and that blurriness is reflected in their communication.
  • Email Transparency: Khan is following Stripe's suit by trying out "email transparency", where everyone is encouraged to CC a "-blackhole" list on every email, so that anyone can find conversations later, but people can ignore the bulk of conversations (everything in the "Blackhole" filter, which we set up on our first day). So far, it's worked great for me - I've never regretted CCing blackhole, and I've also benefitted from responses by people who've found the email in the blackhole. At first, I was a little creeped out by what I saw in the blackhole, I thought "Am I really supposed to see this?" but now it's like, "Yep, we all share everything, that's how we roll." The email transparency is both a way of increasing openness and making it clear that Khan prioritizes openness in all aspects.
  • HipChat: After all that about email transparency: Khan doesn't do much human communication over email. Emails are largely for announcements and automated emails (like from Phabricator). The majority of day-to-day communication happens in HipChat, an IRC-like app. The engineering room has been my go-to room for getting started in the codebase in the last few weeks - whenever I have a question, whoever happens to be around will respond. The computer science room is filled with conversations about current projects and it's how we iterate quickly in development. When someone is working on a new feature, they'll post a screenshot of the WIP, voice any UI concerns, we'll give feedback, designers will post back mock ideas, and the cycle continues. We sometimes have 1-on-1 conversations too, but we try to funnel most conversations into the rooms, so that anyone can search through them later. Now, HipChat can also be quite distracting, so it's not a perfect solution. But then again, what is? (Besides Wave! :-)
  • Open Office: The Khan office is built in this big large space, with a few meeting rooms around the perimeter, then rows of desks, and the main meeting area is smack dab in the center of the room, with no walls. All of the all-hands and dev stand up meetings happen in that meeting area, so it's pretty hard to miss them, and anyone can pull their chair over and listen in. I think this is just an architectural artifact of the space, but the majority of meeting rooms have no ceilings, so there's not a lot of opportunity for keeping secrets. The usual objection to an open office is the high distractibility that can come from the conversations, but the office is eerily quiet for most of the day - and I think that's because all of those conversations are actually happening on HipChat. It's better that they happen on HipChat than in the physical space, since remote employees can chime in, and it's easier for others to chime out if they want to.

All in all, I'm loving how all of our communication is open by default, and it makes me feel good that I'm in an organization where everybody wants everyone to know what's going on and has built that into the culture. I'd love to hear from you about how your company culture ticks in the comments.

Monday, August 12, 2013

Why Do I Speak at Conferences?

When I worked at Google as a Developer Advocate, it was actually part of my job description to speak at conferences, since our goal was to increase the number of developers using the Google APIs and speaking at conferences was one way to achieve that goal. Since speaking was just an assumed part of the job, I never thought very deeply about *why* I spoke. I just thought about which conferences would have the greatest reach and sent out my trip reports after.

Now that I'm no longer in developer relations, it's not an official part of my job description to speak. Despite that, I still get invited to speak and I ended up speaking at 14 conferences and meetups over the last year. I'm lucky to work for companies that support and even encourage me to accept speaking opportunities, and they trust my judgement in deciding how often to speak and which conferences to speak at. Since I am now basically speaking of my own accord, I find myself thinking more deeply about why it is exactly that I speak. I don’t want to speak just because that’s what I’ve always done. I want to understand what it is that I get out of speaking and what I enjoy about conferences, so that I say "yes" to conferences with some degree of confidence in the future. Here goes!


What I Get of Speaking

It gives me a moment to step back and reflect. In my year at Coursera, I worked on many projects, and I would often work on multiple at once or jump directly from one to the other. When I had to put together a talk for a conference, it would force me to take a moment to stop working and just think, asking myself questions like “What is it that I’ve learnt that I think is worth sharing? What have I liked or disliked about the technology we picked?”

I think it’s really important to give a balanced perspective on a topic, and it’s easy for you to convince yourself that you’re doing everything the right way when you’re in moment, so I *need* that forcing function to make sure that I am actually considering all the angles. This is true as much about our approaches to frontend development (which I reflected on in the “Frontend Architectures” talk) and our approaches to social learning (which I reflected on in the “Social learning” talk at I/O).

It gives me a new way to share knowledge I’ve accumulated. When I learn things, I have this burning desire to share what I’ve learnt. I hate thinking that there might be someone out there who might benefit from what I’ve learnt, and me knowing that I’m hoarding that information. If my goal is to reach all those possible people that might benefit, then blogging has the most potential, but speaking has its own benefits. You can share that knowledge in a more interactive way, immediately see how attendees respond, and have fun telling a bit of a story along the way. If the talk is videotaped, then that can reach more people after the event’s over (I rarely ever watch videos of talks myself, but hey, some people prefer that format!).

It’s also not much work to turn a talk into a blog post or a series of posts, and you can focus the posts based on what the audience reacted most to. For example, my localStorage talk became a 2-part article series on Dr. Dobbs, and my “Frontend” talk, that was originally given to an audience of 30 or so, became a blog post with 30,000+ views.

I have to strike a balance between learning new knowledge and sharing what I’ve learnt, of course, and that’s been a struggle for me in an engineering role, but I think I found a good mix of coding, blogging, and speaking this year.

It gives me a way to learn new knowledge from many developers at once. After I give a talk on a particular technology, that gives developers in the audience an opportunity to come up and tell me about their experience with that technology, and often share different solutions from what I shared. I often find out about new tools and techniques this way, and I’ll share the ideas with my colleagues after. We don’t always have the time or resources to try them out, but I always appreciate knowing about new possibilities.

Like all the other attendees, I also get to learn from the presentations of the other speakers. I’ll often write down what my favorite talks were, and send out an email afterwards to colleagues or write up a blog post with a list of my favorites and links to slides.

It gives me an opportunity to meet the amazing developers of the tools I use. We used many open-source frameworks and libraries at Coursera, and conferences love to have the authors of those tools as speakers. Those developers are like our celebrities in the tech world, and hey, even if they’re not the best speakers, it’s like “whoah, the creator of X is speaking!” They often have unique insights because they know what the tool started as when they invented it in their mind, they’ve seen it grown, and they know where they want it to go. They’re also experts on the tool, and the person most likely to be able to answer your burning questions about how to use it.

Now, I could meet those developers as a mere attendee of the conference too, but I find it much easier to meet them as a speaker. Speakers have more inter-networking opportunities, like the speakers dinners, the flights, the walks back to the speakers hotel, the hand-offs between talks. At Webstock, I even found myself accidentally in the same post-conference vacation spot as the keynote speaker Ze Frank, and we wandered around the New Zealand bush together for a few days. Thanks to speaking at conferences, there are so many amazing developers that I’ve had the honor of having long conversations with, and those experiences are invaluable.


How I Decide Where to Speak

Since I’m in the fortunate position of being invited to speak more than I think I probably should, then I must look at each speaking opportunity and decide for myself whether to say yes. It’s incredibly flattering to be invited to speak - the little girl inside me squeals, “you like me! you reallly like me!” when I get those emails - so I really have to force myself to not reply with my gut reaction of “yes, of course!”.

Here are some of the questions I ask myself about the conference:

  • Location: Have I ever been to the location? Will it be good weather at the location? If it’s a foreign city, is it safe for me to wander around? If it’s not safe, will there be locals willing and eager to escort me, or will I be hiding out in my hotel? Do I know anyone else in that location that I want an excuse to visit, anyway? I love traveling and seeing the innards of different cultures, so if I am picking a conference because of it’s location, I want to know that I will actually get to experience that location fully.
  • Distance: How long of a flight is it? Will it be non-stop or be a horribly annoying 3-stop ordeal which could possibly get delayed? How jetlagged will I be? I’ve been invited to conferences in incredibly exotic locales, but then I stick “SFO -> XXX” in kayak.com, see the kind of itinerary I’d have to take to get there, and decide it’s just not worth it. If I was going to turn the conference into a longer vacation with a friend, then sure, it might be worth it to spend so much time traveling, but not if its just me.
  • Timing: Is it during the week or weekend? If its during the week, will I miss our weekly team meetings, show & tells, all hands, or any interesting tech talks? Will it be in the middle of any big launches? If you can’t guess, I prefer weekend conferences, where I don’t feel like I have to sacrifice missing out on things at work.
  • Topics: Does the conference cover a lot of topics that I’m interested in? I’m often invited to more general software conferences, and though I appreciate getting to see topics from way outside my niche, I come away with much less immediately applicable knowledge. On the other hand, sometimes I take advantage of not caring as much about other topics, because it means that I know I can create my slides at the conference itself and not worry about missing anything.
  • My Topic: Will I get to talk about a topic that I’m truly interested in now? Will it be a new presentation or will I recycle an old presentation? I’ve been asked to speak about mobile a few times this year, which I can understand because it’s a hot topic, but I haven’t done PhoneGap in more than a year, so I could not deliver a talk on mobile with confidence. The technology scene changes rapidly in our industry, so if I’m talking about a technology, I better have used that damn recently. As for new versus recycled presentations, I sometimes feel like I don’t have the time to put together a new talk, or that I don’t have any new topic that I’m burning to talk about it, so I’ll only agree to speak if I can recycle a previous talk. I try to be transparent about that, so that the organizers know that it’s not entirely new content.
  • Organizers: Is it organized by a corporation or is it community run? I’ve found that I’ve most enjoyed the conferences that are put together by communities. They tend to care the most about really making it a great experience for both attendees and speakers, and they’ll often go to care to give you a more local experience. The conferences also have a different feel to them - there’s this vibe of “we’re all in this together” that pervades everything, and that’s a great environment for a speaker.
  • Sponsorship: Will the conference pay my way? Most conferences require some sort of travel, and if they do, I will only speak if they’re able to pay for the hotel and flight. Sure, Coursera probably would have been happy to pay for 1 or 2 conferences last year, but they’re a startup, and I don’t think its reasonable to expect them to afford more than that for a single engineer, and conference organizers work hard to get sponsors so that they *can* pay for speakers that need it. And I will ask for it. :-)

I don’t have a scientific way to ask all those questions about a particular conference. As much as I wish I could just stick it all into a formula and get a discrete answer out, I don’t think it’s possible or reasonable. Conferences are experiences, and anything can happen at them, and it’s hard to predict the things you’ll learn or the people you’ll meet that will have the greatest effect on you later. I can ask these questions to try to approximate an answer, and try and reassure myself that I’ve made the right decision, but in the end, it is only an approximation.


What about you?

If you're someone who speaks at conferences, I'd love to hear about what you get out of it and how you decide which conferences to go to. If you're not someone who speaks at conferences yet, then I encourage you to try it out. Start small if you'd like, like with internal demos, lightning talks, local meetups, and work your way up. Find a topic you're passionate about and share your knowledge. I guarantee there's something that you know that other people want to know too.Maybe you'll find you love speaking — I literally feel a surge of adrenalin kick in 5 minutes into every talk the lasts for hours after — or maybe you'll decide it's not your thing. But, hey, it's worth finding out. Report back once you find out!

Tuesday, August 6, 2013

My Next Adventure: Khan Academy CS

To quote my Twitter profile, I "learn, create, teach, and repeat." Well, since I do most of my learning in the space of computer science, that's where I do most of my creating and teaching too.

In middle school, one of my first web pages was titled "HTML iz FuN!" and gave gory details of using the <font> tag to create rainbow colored text. In high school, I helped my dad with his "Saturday Java Academy", where we tricked my friends into spending their weekends learning Java. That's also where I first got asked out - with a Java applet - and of course, I couldn't say no to an object-oriented solicitation. In college, I ran workshops on graphics, 3d scripting, and web programming, the kind of programming that made me love CS, but that we never had time for in our pointer-laden intro classes. At Google, I got to teach developers how to use the Maps API, and as it turns out, there are few things more fun in life than making maps. Nowadays, I get out my teaching urges in GirlDevelopIt web development workshops.

I looked back on all that recently and realized that I've spent many hours of my life teaching programming and thinking about how to teach programming. What order should topics go in? How can students figure out what level they're in? When should students pair, and when should they go at it alone? What exercise will help a student learn a topic and challenge them, but not to the point of giving? In an in-person workshop, what's the allocation of lecture time vs. exercise time? Online, how can you provide hints without making it too easy? Should a student's first language be the most practical or the most newbie-friendly? What language features trip a student up the most?

I find these all to be fascinating questions, and I decided I want to spend more of my day thinking about them - so I found a place where I could do that. Starting this week, I'll be spending my days at Khan Academy, working with John Resig on the Computer Science curriculum that he kick-started last year. I'll be both an engineer, coding up the pieces to make it a great interface to learn, and I'll be a content creator, putting together tutorials and exercises. I also hope to visit schools that are using the curriculum and watch how they incorporate it into classrooms. In this role, I'll be learning how to create tools that teach the next generation about programming, and man, I'm excited.

I know that many before us have thought about how to make programming easier to learn, and I'm looking forward to learning from them. I've started reading related research papers, watching talks, and building up an Amazon wishlist of books on programming and early education. If you have any suggestions to add to those lists, let me know. I've also started to find out about the feedback that Khan has received on the existing curriculum framework, and well, I better finish this blog post soon so I can get started on addressing that feedback.

If you've ever read one of the great blog posts by Ben Kamens or forked one of their open source repos, then you know they have a great culture of sharing and openness - one that I look forward to contributing to. Stay tuned!

Friday, August 2, 2013

JavaScript UI Library Design

Preamble: This write-up is inspired by the talk I gave at BackboneConf 2013.

For the last year, I worked as a frontend engineer at Coursera. We constantly found ourselves needing UI widgets to decorate our interfaces, like modals, popups, tooltips, uploaders. You know, the same widgets that 99% of websites need, plus a few niche widgets.

We wanted to use the same UI widget libraries both in the legacy global-variables-roam-free codebase and the shiny-requirified-backboney codebase. We started with what most developers start with, jQuery plugins, but then we ended up coming up with our own way of architecting UI plugins to meet our particular constraints and satisfy our particular desires.


On jQuery Plugins

Now, don't get me wrong; I'm forever grateful for jQuery and its plugins ecosystem. John Resig released jQuery in 2006 with a plugin mechanism from day 1, and the first third-party jQuery plugin came out only a few weeks later. A year later, the community launched the plugin repository, further encouraging developers to create and share their plugins. They also launched jQuery UI soon after, which gave developer more of an architecture and base for UI plugin development. jQuery plugins became the defacto standard for UI library development and thanks to jQuery encouraging developers to share their creations, there are now thousands of plugins for developers to pick from.

But, that doesn't mean that jQuery plugins are perfect. To begin with, many jQuery plugins lack an architecture or vary wildly in their internal architecture. The original jQuery plugin "architecture" was as simple as attaching a method to $.fn and processing the passed in element. jQuery UI eventually introduced a generic widget factory with more of an architecture, and developers like Addy Osmani wrotes articles on best practices for plugin design. But it's hard to know how many plugins actually follow those best practices, particularly the older ones, and from a purely anecdotal perspective, I've gone through the source of enough plugins to suspect that the majority do not. Now, the internal architecture wouldn't matter if plugins were just blackboxes that did what you wanted them to do. But, they're not - they are chunks of JS code that your code depends on, code that you will likely find yourself debugging and patching to better suit your needs. If they follow a set of best practices and standard architecture,then they're more likely to work well and be easier for developers to dive into.

Besides that, jQuery plugins are inherently dependent on jQuery. Yes, most websites use jQuery these days (including all of Coursera), but it'd be better if there was a standard way to write UI libraries that did not depend on any libraries, and the UI library would only bring the libraries in that it truly needed. Plus, some of the best plugins are dependent on jQuery UI, since it includes the widget factory and offers features like draggable/sortable, and jQuery UI is a heavy addition to an app that isn't otherwise using it. It's also often difficult to use the jQuery UI JS without the CSS and its subsequent look & feel.


Rethinking UI Libraries

After trying to write some custom Coursera UI widgets as jQuery plugins, we decided that it might be more useful for us to start over and figure out how to architect our UI libraries for everything that we wanted out of them. We wanted many of the things that developers want in jQuery plugins, like customization and events, but we also wanted zero dependencies, AMD-compatibility, designer-friendly declarative usage, and more. As an example, I'll step through the creation of a library that emulates <marquee> functionality, because, seriously, there are so many times in life that I need a marquee.


The Basic Marquee Library

We'll start off with the basic library. The library user will write this HTML:

<div id="marquee-me">Yo Wassssup!</div>

And write this JavaScript:

var marquee = new Marquee(document.getElementById("marquee-me"));
window.setTimeout(function() { marquee.stop(); }, 5000);

The code that makes it work is in this JSBin. I've used standard OO JS to create a Marquee object, setInterval to start the element moving via CSS positioning, and clearInterval in the stop method.


Hidden Private Functionality

As I learned from my many years on the Google Maps API, developers using a JS API *will* find every single possible un-documented method and use them in their production code, and they'll get mad once that method stops working. After that experience, my approach now with libraries and APIs is that you should try to keep everything private until absolutely necessary; until developers are groveling at your doorstep for the functionality and you feel confident enough that you can test and maintain that functionality. Hiding functionality isn't as crucial for internal libraries, but I still think it's a useful to make it clear which methods a library author originally intended to be used by the outside.

In the original code, library users could easily call marquee.moveItMoveIt(), a method that I intended to be private (I'd never expose such a silly name!), so I want to restrict that. In the new code, I've wrapped everything in a MarqueeModule that includes a _private object with the moveItMoveIt method as a member as well as the Marquee object which now only has the stop method. Then MarqueeModule returns the Marquee object, and window.Marquee is set to that return value. There's no way now for library authors to access _private, since that's a local variable that was never exposed or returned.


Idempotent Constructor

We developers are forgetful. Okay, at least I am, and I want to make sure that if I call a constructor twice on the same element, I only really construct the UI component once. That way, I don't have to worry about checking everywhere that a UI component may have been constructed and I can just call it again for good measure. This is the fancy concept known as "idempotence".

In the previous code, if a library user called Marquee twice on #marquee-me and tried to stop() it, the marquee would go on forever and ever, because it started two setInterval's. Now, we wouldn't want that.

In the new code, I've added a private getOrMakeMarquee method that checks if there's already a Marquee object associated with the element, returns that if so, and constructs a new one if not.


Customization and Defaults

When a developer can customize their usage of a UI library by just specifying a few options, it gives them a way to change the library without having to go into the code or write their own. That's why many popular libraries boast many options (just see the Select2 demo page for an example). Of course, more options means more to maintain and test, so we don't want to add options just because, we want to add them because we have some inkling of how usage will vary of the library.

For Marquee, we might realize that library users will want to vary the distance and direction:

var marquee = new Marquee(document.getElementById("marquee-me"), 
    {direction: 'forwards', distance: 100});

They also might want to re-specify options later, and have the library pick up the new options:

var marquee2 = new Marquee(document.getElementById("marquee-me"), 
       {direction: 'backwards', distance: 1});

To support options in the new code, I added a defaults object at the top that clearly documents every option, its default value, and its possible values. I then added the customizeMarquee method that merges the passed in options with the default values, and I call that both from the constructor and the getOrMakeMarquee method.


Declarative Customization

The Coursera designers like to work in HTML and CSS to craft the interfaces, and they even have Github accounts and local servers running on their machines to make it possible for them to actually check out branches, tweak HTML, and send changes for review. They're not quite at the stage yet of JS, and given the non-linearity of our JS, it's not so easy to poke around for newbies, so the frontend engineers try to make it possible for them to edit as many things about the look and feel as possible in HTML and CSS alone. That means that when it comes to UI libraries, they should be able to customize the widgets without diving into the JS. And hey, as it turns out, developers like being able to customize in the HTML as well.

For example, for the Marquee library, it should be possible to use data attributes to customize it like so:

<div id="marquee-me" 
     data-marquee-direction="backwards" 
     data-marquee-distance="5">
     Yo Wassssup!
</div>

To support that in the new code, I modified the customizeMarquee method to check the data attributes for each option, and use that if none were specified in the JS.


Declarative Construction

Why should developers and designers have to use JS to initialize a UI widget at all? We could just have them add a specific data attribute that indicates an element should be transformed, and as long as the page included the JavaScript, we'd transform all the matching elements.

For the Marquee library, we could add an attribute like data-marquee:

<div id="marquee-me" 
     data-marquee
     data-marquee-direction="backwards" 
     data-marquee-distance="5">
     Yo Wassssup!
</div>

To support that in the new code, I added a new method called start to the public object. That method takes in an element, searches for any elements with the data-marquee attribute, and calls getOrMakeMarquee on them. We call that method on document.body when the library is loaded, so it can pick up anything that exists already. If we're using this library in a Backbone app where we often construct the HTML after the fact, then we'll still need to call that method on the view element once everything's rendered. Theoretically, we could use Mutation Observers to find out about DOM changes that introduce new data-marquee elements, but that's a new and not widely supported browser feature.


Observable

Another way to let developers customize their use of a library is to let them specify callback functions to happen at particular times in the lifecycle of a UI widget. Many libraries still do this via options, letting developers specify things like an onClick callback. That approach isn't the best, though, since it means only one callback can be assigned, and it clutters up the options hash. The preferred approach is to let developers add event listeners to the widget for whatever event they're interested in. Just like with options, events should be tested for and maintained, so we only want to fire those events that we are prepared to support.

In the Marquee library, we might realize we want library users to find out when the marquee reverses direction, like so:

var marquee = new Marquee(document.getElementById('marquee-me'));
marquee.on('reverse', function() {
  document.getElementById('marquee-me').innerHTML = marquee.direction;
});

To support that in the new code, I added an EventTarget object (copied from this article). and made the Marquee object extend it. Then I can call this.fire('reverse') at the appropriate time.


AMD-Compatible

At Coursera, there are some codebases that use RequireJS to manage dependencies, and some codebases that just shove everything into the global namespace and hope for the best. Not that I'm advocating for the latter, but hey, I bet there a lot of codebases out there that do that, especially smaller ones. We want our UI libraries to work equally well in each codebase, and not have to use separate copies for each.

In an AMD environment, we should be able to use Marquee like so:

define("lib/marquee", function(Marquee) {
  var marquee =  new Marquee(document.getElementById('marquee-me'));
});

To support that in the new code, we added a conditional at the end which checks if define is defined in the AMD way, and if so, it wraps the module in define. If not, then it attaches it to window.Marquee like before.


Declared Dependencies

Most UI libraries will indeed depend on additional libraries - and that's understandable. The code in a UI library should be focused on the unique functionality of that library, not on re-inventing the code of libraries past. So we want a way to bring in those dependencies that works in both the AMD and non-AMD environments.

For the Marquee library, I would likely bring in jQuery for my DOM manipulation and data attributes, as my current code is nowhere near being cross-browser compatible. You can see that in this code; all I do is change the define block at the end and pass the $ to MarqueeModule at the top.

I would also use LucidJS for the event emission, as it's a great little library that's easy to mix-in to an object in a non-obtrusive way. You can see that in this code.

Many of the Coursera UI libraries also bring in Underscore for data manipulation, extend to process options, debounce, and some bring in Q for promises.


Testable

As I've mentioned in many of the above points, we should have tests for all publicly exposed functionality, options, and events. In fact, we should probably test UI libraries even more than our normal application JS, because we will be using these libraries multiple times, and it is more likely that a developer from another part of the codebase will accidentally "abuse" library, using it in a way that the author never expected. If there are tests for the library, then it's easy to add regression tests for the new and interesting ways that the libraries gets used, or add a test that ensures it can't get used that way.

For the Marquee library, I wrote a small suite of 7 tests that check construction, options, declarative usage, and events. That suite is built on Mocha and Chai, but the tests could just as easily be written in QUnit, Buster, or Jasmine. The typical Coursera testing stack is Mocha and Chai with JSDom, so that the UI library tests can be quickly run outside of a browser environment as well.

I did run into a problem testing Marquee that I also ran into with Coursera libraries: now that we've hidden the private functionality, how can we test them? We don't usually care about calling them directly (though there are cases where testing that could be useful), but there are times when it would be useful if we could use Sinon to stub out private functions and simply verify that they were called during the execution of a public function. There are various posts like this one the discuss testing private functions in JS, and I don't think there's one technique that's clearly the best yet.


Documented

Developers should not have to read through a library's code to understand how to use it. Even if you've written the most beautifully usable code in the world (at this point, I will remind you how most parents think their babies are beautiful, when in fact they're screaming trolls). At the minimum, add a comment at the top which shows an example of using the library, both the HTML and the JS needed. If you want users of the library to appreciate you even more, add more examples of advanced configuration, write up an explanation of why the library exists and what future work remains, and point to examples of real world usage of the codebase. Remember, you want your colleague to look over at you with an adoring look on their face, not a begrudged glare.

For the Marquee library, I added a readme with a short history and usage examples.

Remember: when in doubt, document.


Real World Examples

Now that we've walked through the Marquee library together, I've shown you many of the design patterns that power the Coursera UI libraries. You might be wondering what these look like in a "real library", as you likely suspect that the Coursera designers never let me get away with Marquee-ing everything. You'd be right...so here are some actual Coursera UI libraries.


ReadMe

The ReadMe library displays a banner at the top of a page, which will be displayed until a particular date or until users close it a certain number of times. The Coursera frontend lead built this after constantly wanting banners like this to announce new functionality to students and admins, and it's now in heavy use.

To use this library, we'd write HTML like this - notice how we can stick data-readme-close on any element to tell the library that clicking it should close the banner:

<div data-readme="watchlist-announcement" data-readme-show-count="1" data-readme-show-until-closed="data-readme-show-until-closed" data-readme-show-expires="Jun 15, 2013" class="hide readme">  We now give students the ability to "watch" classes they're interested in, which replaces the need for TBA sessions.
  <a href="https://class.coursera.org/mooc/forum/thread?thread_id=472" target="_blank" data-readme-close="data-readme-close">Read more here.</a>  <div data-readme-close="data-readme-close" class="readme-close-icon"><span class="icon-remove"></span></div></div>

Then we'd call ReadMe on the element:

new Readme(this.$('.readme'));

You can see the full code here.


Modals

Like any proper webapp, Coursera uses a lot of modals. The modals library was built as a replacement for the Bootstrap modals library (which didn't do enough) and the fancybox library (which did too much and was heavy), so it was designed to let developers use the Bootstrap CSS if desired, but not force it.

To use it with Bootstrap CSS, we'd write HTML like so:

<div data-modal-overlay-class="coursera-overlay-dark" class="modal coursera-course-selfstudy-modal hide"> 
   <div class="modal-header"><h2>What is "self study"?</h2></div>
   <div class="modal-body"><p>Self-Study bla bla bla....</p></div>
   <div class="modal-footer"><button data-modal-close class="btn btn-primary">OK, I got it!</button></div>
</div>

We could then trigger it via an HTML anchor:

<a data-modal=".coursera-course-selfstudy-modal" role="button">?</a>

Or we could programmatically open it:

Modal(this.$('.coursera-course-self-study-modal')).open();

You can see the full code here. The start function is a bit more interesting in the Modals library, because there should only ever be one Modal open at once, so it takes care of closing previous modals and enforcing the singleton nature of this UI widget.


PopUps

The Popups library is similar to the Bootstrap popovers library, a UI component that pops up next to an anchor, and remains there until the user moves away. Coursera uses it for dropdown menus, hover cards, and more.

To use it, we'd write HTML like this for the anchor. Yes, it's a lot of HTML, and that's because we need our UI to be accessible, so we must add the appropriate ARIA attributes that signal both that the anchor is a button and that it is associated with an expanded menu.

<li class="course-topbar-nav-list-item"
    tabindex="0" role="button" aria-haspopup="true"
    aria-expanded="false" aria-owns="course-topbar-aboutus"
    data-popup="#course-topbar-aboutus"
    data-popup-bind-open="mouseenter" data-popup-direction="se">
    <a>About <i class="icon-caret-down"></i></a>
</li>

We'd write this HTML for the actual popup content - no ARIA required here, as the library itself adds what's necessary. We wrote the ARIA roles manually in the anchor HTML, as we don't necessarily run the JS until the anchor is interacted with, and it needs to be accessible from the beginning.

<div id="course-topbar-aboutus" class="course-topbar-sublist">
    <a class="course-topbar-sublist-item" href="/about/jobs">Jobs</a>
    <a class="course-topbar-sublist-item" href="/about/team">Team</a>
</div>

You can see the full code here. A few things to notice: 1) it documents the accessibility requirements clearly, 2) it enforces that only one popup is open at once, like modals, 3) if the specified activation event is mouseenter but the current browser is a touch device, it uses click instead.


And Many More

Those are some of the most frequently used UI libraries at Coursera, but as you can imagine, there are many more: a custom A/B testing framework, a media uploader using Transloadit as a backend, a rich text area with Markdown and HTML support, tooltips, calendar date picker, affix, draggable, sortable, etc. They vary in how much they adhere to the design patterns I've laid out here, but going forward, the frontend lead tries to enforce them in reviews of new libraries and backport them to old libraries. It's important that new developers that join the engineering team are presented with a consistent architecture, because they'll naturally follow that architecture when building new libraries.


Wrapping It Up

You might be looking at everything I just showed and thinking, "wait, couldn't we do all that with jQuery plugins?" I bet that you could, and I bet there are jQuery plugins out there that do all of that and more. We just went down the route of starting from scratch to see what we'd end up with at the end, given our particular constraints and desires, and I'm sharing what we came up with. I encourage you to share your own best practices for UI library design in the comments, or try out some of the ideas here in your own projects and report back.

Thursday, August 1, 2013

The JavaScript Rap

Last year, I gave a talk at EverywhereJS called "JS in the front, REST in the back" about our frontend-heavy architecture and the advantages of it. I thought that the title had a nice rhyme to it and that it almost seemed like to start of a rap, and I always like an excuse to sing and dance in my talks, so I started an EtherPad with one stanza in it, and asked Twitter to take it from there.

I discovered that my Twitter followers are all rhymers at heart, and they should probably all just give up coding and spend their time penning mad rhymes. But, actually, they're also JS ninjas: their rhymes mentioned the most obscure of JS features and the new ES6 hotness. Since the etherpad gets "vandalized" a lot, I've decided to snippet it here for posterity. If any of you actually record yourself rapping this whole thing (or country singing it, that's cool too), please let me know. It would make my day/life.

Update: I dared Adam Sontag to deliver the rap as the closing for BackboneConf, and he got through a whole 40% of it. Check out the video here. Best conference closing ever.

Update 2: You can now listen to JavaScript speaking the rap. Amazing. Better than I could ever do it.

Give me the Mic
Crockford and Eich
From Netscape to Node
It’s been quite a hike
 
JS in the front, REST in the back
Ain’t it time you changed your stack?
Server-side rendering? That’s just whack
Once you go Backbone, you never go back
 
Unobtrusive set us free
It all blew up with jQuery
Now it’s MVC with TDD
Ain’t got time for PHP
 
Onclick to Require was such a ride
With GitHub code ain't got no where to hide
my lack of globals is a point of pride
I’m hitting my stride on the client-side
 
Stop testing IE 6, it’s a trap!
Been crap since way back, everybody knows that
Standards make dev such a snap
And don’t get me started on space vs. tab. [mic drop]
 
Use Grunt, watch it automate on a dime
Don’t waste no coding time
AMD will make you feel cool
Loose Coupling so you won’t look like a fool
 
Just sit right back hear the tale
Brendan’s gonna make, we cannot fail
We ain’t got three hours, it’ll take ten days
Born from scheme and self in a lispy haze.
 
And amp, semicolon, the rhymes, I got plenty
I got the space encoded, fool it’s percent twenty
my var’s locked in closure, that’s dope
Ain’t no bleedin or leakin’ since I’m in the right scope.
 
Yo, JS is /the/ form,
where I code like a storm
Free from spaghetti!
Fierce like the Serengeti
If that bug’s hard to track
console’s got your back
 
Code it DRY, code it right
Browser, server, world; its all in sight
Use the remote debugger
Like there ain't no other
 
You code in JS, but you mixing the types
And always forget the syntax for “splice”
To type “double equal” is like rolling the dice
And you scared to death … of prototypes
 
It’s time to stand up and get some respect
Just go to ECMA and read the fucking spec
Unpuzzle, unlock it, uncode and decrypt
And gain yourself power of true JavaScript
 
You add number to string and string to array
Divide it by object (you know it’s ok)
The prototype chain you can see through the code…
It was a great journey from Netscape to Node.
 
`eval` is evil and `with` is whack
F*ck classes — you can have ’em back
This is the generation of floating math
No tail calls in this giant stack
 
Var i, math dot pie in the sky
Fly tries to catch zero size
arrays with new prototypes are lies
disguised as wise overrides
prefix with java, ecma, mocha, and live
script all day and all night
microsize your JS lines
but don’t self minify
above all else, yo, f*ck static types
 
Go async and then you’ll never look
(this line will run before the last’s call)
back. Stop waiting for some slow IO
and start using four cores in your MacBook Pro.
fat arrow lambda, func’d the funky
close over this, ya JavaScript junkie
comma abuse, ASI hack
truth-y compare, you'll wanna redact
Bask in the glow, open/close brace
of any indent, Insignificant whitespace
`arguments` array? It isn’t that hard
You ain’t gotta call Captain Picard
 
My macros are sweet, my models aren’t fat
My build script’s complete, unit test — all that
Controllers are trim, view models fine
E.C.M.A. - TC-39b
 
functional code, is what I’m rockin’
dot foreach and map, reduce ain’t lockin’
those mutable props, makin’ me sneeze
I think I’m allergic, object dot freeze
 
while cache clonin’, weakMap for me
gimme some has-Own-Prop-er-ty
awaiting for no one, renaming a file
async is alright, actor callback style
 
Google Go code-gen, in fat reams
Don’t need no types, or agile teams
Slingin’ that node, gimme pipes, gimme streams
Gimme that Harmony, of our dreams
 
My code is lean, it ain’t all swollen
I love my braces and my semicolons
It’s ok now, don’t you be tight-lipped
it’s ok to say you hate CoffeeScript!
 
It was all a dream 
I used to code vanilla JS on the scene 
Now I got Backbone and Zepto all up in the IDE
JS is blowin’ up like I thought it would 
New frameworks, but same language in the hood.
And it’s all good.
So if you don’t know, now you know, coders. Uh.
 
Hey yo server siders clogging up the rear
Stop making it complex, I’m starting to tear
try the frontend, that’s where it’s at
Power to the coders, got nothin’ to catch

Saturday, July 27, 2013

My Year at Coursera

Just over a year ago, I realized that my passion in life is education and announced here that I would be joining Coursera as a frontend engineer to help them evolve online university-level education. It's been an incredible year, one where I've learnt a massive amount about frontend engineering, startup culture, and online education.

I've made the difficult decision to move on from Coursera engineering for a different role in the education space, but I really appreciate the time that I had at Coursera and I want to take a moment to look back on it here:

The Projects

I got the opportunity to both make new parts of our interface and re-think existing bits, both from the technology and usability point of view:

  • Made the first team page (screenshot)
  • Rewrote the course catalog and frontpage (screenshot)
  • Wrote the interface and APIs for our social profiles (blog post)
  • Improved the messaging of quiz deadlines to reduce student confusion
  • Re-wrote our Django admin in Backbone/APIs instead (blog post)
  • Ported our legacy codebase to Bootstrap 2 (blog post)
  • Re-wrote our forums in Backbone/APIs instead (blog post)
  • Coded the feature detection and half of the sign-up process for Signature Track (blog post)
  • Wrote an iCal feed for deadlines in classes (blog post)
  • Made a way for professors to connect forums to lectures
  • Improved the performance of our frontend (blog post)
  • Created a reporter wizard for students to get help and report bugs
  • Wrote hundreds of tests for the frontend (blog post), Django APIs, and legacy PHP code (blog post)

The Technology

I found myself in a stack of many technologies that I'd heard of but never used on a real project, so this was a great opportunity to learn them on a deeper level:

  • Frontend tools: Backbone, Underscore, Jade, Stylus
  • 3rd party APIs: Transloadit, Badgeville, Google Maps Places API
  • Languages: Python, PHP, Scala
  • Web frameworks: Django, Play
  • Amazon Services: S3, CloudFront, RDS, EC2, CloudSearch
  • MySQL and phpMyAdmin

The Culture

We went from 15 to 50 people over the course of the year, and during that time, we cultivated our own unique Coursera culture, one of fun and learning:

  • We came up with fun Formal Friday themes, when we got bored of the formal thing - my favorite was when everyone dyed their hair pink to match mine.
  • We started a Show & Tell on Mondays, and are still doing it now, with people across the whole company sharing their hacks, their progress, even their family vacation photos.
  • We ran in the MudWarriors challenge together and practiced our handstands in the hallways.
  • We started an underground Twitter account.
  • We invited startup founders, engineers, and our favorite Coursera professors to give tech talks about their area of expertise, always with lively discussions after.

The People

The Coursera team is a bunch of the smartest and most passionate people I know. Many of them used to be teachers or TAs, they come from all over the world, and they're all motivated by the mission to improve education for everyone. They're also a whole lot of fun. :-)

If you want to join Coursera, they are pretty much always hiring, join them!

...And stay tuned to find out about my next adventure.