<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Bocoup Blog</title>
    <description>This feed contains all articles from the Bocoup Blog.</description>
    <link>http://weblog.bocoup.com/feed</link>
    <pubDate>Wed, 22 May 2013 04:22:12 +0000</pubDate>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/bocoup" /><feedburner:info uri="bocoup" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
        <title>Open Peer and the Frontiers of WebRTC</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/open-peer-and-webrtc</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/eM9SyMHtlHs/open-peer-and-webrtc</link>
        <author>Mike Pennisi</author>
        <description>&lt;p&gt;At Bocoup, we love working on the latest problems in front-end development such
as &lt;a href="http://weblog.bocoup.com/category/web-workers/"&gt;parallel processing&lt;/a&gt;, best
practices in &lt;a href="http://weblog.bocoup.com/category/open-web-apps/"&gt;web application
development&lt;/a&gt;, and &lt;a href="http://weblog.bocoup.com/category/media/"&gt;media-rich
experiences&lt;/a&gt;.  This is why we
consider the folks at &lt;a href="http://hookflash.com/"&gt;HookFlash&lt;/a&gt; kindred spirits; they
have made browser-based peer-to-peer communication their “thing”. We recently
had the privilege of working with the HookFlash team, and (as can only be
expected when collaborating with passionate, talented individuals) we learned
quite a bit.&lt;/p&gt;

&lt;h2 id="for-those-late-to-the-party"&gt;For Those Late to the Party&lt;/h2&gt;

&lt;p&gt;So much of today’s web is about communicating with one’s peers, the term
“peer-to-peer” (or “P2P” for short) can seem like old news. When you write a
Direct Message to someone on Twitter, isn’t the text delivered from one peer to
another?  Really though, the term is less about &lt;em&gt;who&lt;/em&gt; is communicating and more
about &lt;em&gt;how&lt;/em&gt; they are communicating. A true “peer-to-peer” channel does not rely
on any sort of specialized central service (i.e. twitter.com in the previous
example); all the messages travel directly from the sender to the recipient.*
This communication model is highly sought-after because it enhances privacy,
security, robustness, and accessibility far beyond what is possible within
“mediated” channels.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.w3.org/2011/04/webrtc/"&gt;WebRTC&lt;/a&gt; is a developing standard to
facilitate streaming data transfer between web browsers. It defines a
JavaScript API for generating the information that clients need to communicate
in real-time (this is called the Session Description Protocol, or SDP for
short). Creating such rich communication channels is no small feat (check out
&lt;a href="http://www.webrtc.org/reference/architecture"&gt;the architecture reference&lt;/a&gt; to
get an idea of the complexity), but it isn’t the end of the story.&lt;/p&gt;

&lt;h2 id="this-space-intentionally-left-blank"&gt;This Space Intentionally Left Blank&lt;/h2&gt;

&lt;p&gt;If we take the extraordinary service rendered by the WebRTC API for granted
(which we do only temporarily), we can more clearly see its limitations. Sure,
peers are able to connect with each other directly, but how do they negotiate
connections? What if the peer does not want to immediately accept a call? What
if she is away from her device? How do the peers end the call? These questions
fall under the purview of “signalling”, and the WebRTC specification makes no
attempt to address them.&lt;/p&gt;

&lt;p&gt;This is no oversight, however. Defining a fully-featured signalling protocol is
a challenge unto itself, but it is tangential to the technical challenges that
the WebRTC specification set out to address. As it stands, it has taken the
standards body years to define a solution for streaming data transfer (and it
still isn’t complete). By intentionally limiting the scope of the
specification, the WebRTC working group is able to arrive at consensus far more
quickly.&lt;/p&gt;

&lt;p&gt;WebRTC defines all the functionality that developers around the world need to
begin experimenting with their own protocol implementations. Any website can
use WebRTC to implement fully-featured peer-to-peer applications (and indeed,
&lt;a href="https://apprtc.appspot.com/"&gt;many&lt;/a&gt; &lt;a href="https://gittogether.com/"&gt;already&lt;/a&gt;
&lt;a href="http://twelephone.com/"&gt;have&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Unfortunately, without a standard, each of these web applications is a silo
unto itself–there can be no communication across web sites. Thanks to WebRTC,
web developers have all the tools they need to prototype open standards for
signalling over WebRTC.&lt;/p&gt;

&lt;h2 id="enter-open-peer"&gt;Enter Open Peer&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://openpeer.org"&gt;Open Peer&lt;/a&gt; is Hookflash’s open-source signalling
protocol. (Its open nature is important because it means anyone is able to
create compatible applications for any platform, free of charge.) First and
foremost, it addresses the needs described above. But since peer-to-peer
communication has so much more potential than simple actions like “hang up” and
“reject call”, Open Peer implements far more powerful abstractions.&lt;/p&gt;

&lt;p&gt;For one, the concept of “identity” has been built into the protocol. This
enables users to find each other by some persistent, human-readable name (think
“Mike Pennisi” instead of &lt;code&gt;2001:0db8:8ba3:4043:1020:812e:b3d0:7aa4&lt;/code&gt;). But
instead of relying on some centralized authority to provide this name,
identities in Open Peer are federated (think e-mail addresses instead of
Twitter handles). It also recognizes the fact that people already &lt;em&gt;have&lt;/em&gt;
identities with “legacy” systems (e.g. phone numbers and e-mail addresses) and
provides hooks for them.&lt;/p&gt;

&lt;p&gt;Support for identities necessarily requires the addition of some infrastructure
into the protocol. If you want to be able to find your friend by name, some
service must exist that knows how to locate him. After you’re connected, true
peer-to-peer communication can begin, but the reliance on third-party services
remains something of a necessary evil for the niceties of identities.&lt;/p&gt;

&lt;p&gt;Open Peer attempts to mitigate the security and privacy risks by making the
infrastructure as distributed and stateless as possible. The servers have no
sensitive data, and they are completely interchangeable. This de-incentivizes
the servers as a target for hackers and severely limits the abilities of
malicious administrators.&lt;/p&gt;

&lt;p&gt;By making a distinction between the concepts of identity and location, Open
Peer enables a particularly interesting use case. Consider the following
hypothetical situation:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You’ve just won a contest! The prize? A ten-minute phone call with your
favorite performer, Englebert Humperdinck! Tonight, he will be calling you
online using the Open Peer protocol. Now, the Dinck is a popular guy–not
anyone can just call him at will. Despite this, when you receive a call at
6:00PM, you can be 100% positive that the caller is, in fact, the legendary
British hearthrob. Once your ten minutes is up, Englebert ends the call, and
you are left with a sense of awe, but (and this is the important part) no
means to call him back. There’s no &lt;code&gt;*-6-9&lt;/code&gt; by default. Of course, if you guys
had really hit it off, there would be nothing to prevent the crooner from
sharing his contact details, but this is completely optional.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Users are only able to locate a given peer if they know their “name” &lt;em&gt;and&lt;/em&gt;
their “find secret”. By allowing peer-to-peer communication without the
exchange of this information, Open Peer enables scenarios like the one
described above. You’ll find more about this concept in &lt;a href="http://docs.openpeer.org/OpenPeerProtocolSpecification/#TheMakeupOfThePublicPeerFile"&gt;the documentation of
the Public Peer
File&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="the-future-of-p2p"&gt;The Future of P2P&lt;/h2&gt;

&lt;p&gt;While we find it easy to get excited about the promise of the Open Peer
protocol, it’s important to remember that there is still a lot of work to be
done, and nothing is set in stone.&lt;/p&gt;

&lt;p&gt;WebRTC remains unfinished. The specification itself is still being written; you
can get involved through &lt;a href="http://lists.w3.org/Archives/Public/public-webrtc/"&gt;the WebRTC working group’s public mailing
list&lt;/a&gt; and the
&lt;a href="http://lists.w3.org/Archives/Public/public-media-capture/"&gt;&lt;code&gt;getUserMedia&lt;/code&gt; API mailing
list&lt;/a&gt;. &lt;a href="https://plus.google.com/113817074606039822053"&gt;The WebRTC
Google Group&lt;/a&gt; and
&lt;a href="http://webrtc.is"&gt;webrtc.is&lt;/a&gt; offer coverage on the latest developments.  And
don’t forget that both Firefox and Chromium are open-source, so you can get in
on the implementation as well. You can find &lt;a href="https://developer.mozilla.org/en-US/docs/Introduction"&gt;a guide for contributing to
Firefox here&lt;/a&gt; and &lt;a href="http://dev.chromium.org/developers/contributing-code"&gt;a
guide for contributing to Chromium
here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Open Peer is under heavy development as a collection of open-source projects.
You can find SDK’s for a number of environments on GitHub:
&lt;a href="https://github.com/openpeer/opios"&gt;iOS&lt;/a&gt;,
&lt;a href="https://github.com/openpeer/opbb10"&gt;BlackBerry&lt;/a&gt;,
&lt;a href="https://github.com/openpeer/op"&gt;C++&lt;/a&gt;, and &lt;a href="https://github.com/openpeer/opjs"&gt;the
browser&lt;/a&gt; (Android support is in the works).
Protocol nuts will no doubt be interested in reviewing &lt;a href="https://github.com/openpeer/op-docs"&gt;the full
specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course, the space for signalling protocols is wide open.
&lt;a href="http://peerjs.com"&gt;Peer.js&lt;/a&gt; is another project that attempts to address
signalling concerns for WebRTC. Though if you’re particularly opinionated, you
might choose to propose a brand new open standard of your own design. If this
is the case, all we ask is that you try to learn from the current proposals and
those that have come before (e.g.
&lt;a href="http://xmpp.org/about-xmpp/technology-overview/jingle/"&gt;Jingle&lt;/a&gt;,
&lt;a href="http://www.cs.columbia.edu/sip/"&gt;SIP&lt;/a&gt;, and
&lt;a href="http://www.pdos.lcs.mit.edu/chord"&gt;Chord&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;From a developer’s perspective, this may be the best aspect of the open web: if
you’re passionate about the problem, opportunity abounds.&lt;/p&gt;

&lt;p&gt;* - &lt;em&gt;Sure, there will always be machines like routers and switches between the
  peers, but these devices have no privileged information and are completely
  interchangeable.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/eM9SyMHtlHs" height="1" width="1"/&gt;</description>
        <pubDate>Thu, 2 May 2013 12:26:14 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/open-peer-and-webrtc</feedburner:origLink></item>
      <item>
        <title>Welcome Kacie Cabral</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/welcome-kacie-cabral</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/1vNyudUPWkI/welcome-kacie-cabral</link>
        <author>Jory Burson</author>
        <description>&lt;p&gt;The next time you stop by the Bocoup Loft, there will be a new face greeting you at the door - Kacie Cabral. As Bocoup’s newest team member and Office Assistant, Kacie will be helping keep the Bocoup Loft in top-form for meetups and community events in addition to organizing travel and inventory for her fellow Bocoupers.&lt;/p&gt;

&lt;p&gt;Most recently, Kacie has been attending college at Bristol Community College where she is studying Computer Information Systems. When the time comes, Kacie plans to join Bocoup’s engineering team and build apps for the Open Web. Kacie is a very fast learner - there’s no doubt that time will come sooner rather than later!&lt;/p&gt;

&lt;p&gt;At Bocoup, we realize great programmers come from all manner of educational backgrounds, and we’re thrilled to be part of Kacie’s engineering growth. Join us in welcoming her to the team!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/1vNyudUPWkI" height="1" width="1"/&gt;</description>
        <pubDate>Tue, 30 Apr 2013 11:30:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/welcome-kacie-cabral</feedburner:origLink></item>
      <item>
        <title>The Dimensions of Web Design</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/the-dimensions-of-web-design</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/nmAzMMZPel4/the-dimensions-of-web-design</link>
        <author>Greg Smith</author>
        <description>&lt;h2 id="the-5-dimensional-web"&gt;The 5-dimensional Web&lt;/h2&gt;

&lt;p&gt;Today’s web has at least five dimensions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Width&lt;/li&gt;
  &lt;li&gt;Height&lt;/li&gt;
  &lt;li&gt;Time - Site content is constantly changing and being added.&lt;/li&gt;
  &lt;li&gt;Hardware - Content needs to be usable on a variety of devices.&lt;/li&gt;
  &lt;li&gt;Software - Different users have different browser capabilities and settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Good websites embrace this complexity as a competitive advantage. Bad websites try to do things the old way and it doesn’t work.&lt;/p&gt;

&lt;p&gt;The best part is that this mindset actually makes it &lt;em&gt;easier&lt;/em&gt; to design websites. Taking advantage of the web’s best qualities means cutting with the grain*. Going with the flow. If you’re fighting to put a square peg in a round hole, you’re probably making your user experience worse anyway. Learn to let go and do things the web way.&lt;/p&gt;

&lt;p&gt;Welcome to the future. The web is 5-dimensional. Here is your hypercube. Now let’s get to work.&lt;/p&gt;

&lt;p&gt;*I mean like wood, not steak. Cut against the grain of steak so it’s more tender.&lt;/p&gt;

&lt;h2 id="content-is-god-emperor"&gt;Content is God-Emperor&lt;/h2&gt;

&lt;p&gt;Let’s start with a goal. Every website has a different purpose, but it can always boil down to providing content. Even web applications like Gmail provide content: the added complexity is that you can interact with and create content as well.&lt;/p&gt;

&lt;p&gt;Since all websites present content, all websites should do it well. Content should be easy to find and easy to understand. Content is King. In fact, Content is God-Emperor of Dune.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;#1 goal of web design: Make it easy for people to find and understand your content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design is not just “make it look pretty”. Pretty things are good because &lt;a href="http://www.amazon.com/Emotional-Design-Love-Everyday-Things/dp/0465051367"&gt;they work better&lt;/a&gt;, but that’s just one way design can help you meet your goals. Good web design can make information easier to understand. It can make content easier to find. It can make it clear what you’re expected to do. It can inspire trust.&lt;/p&gt;

&lt;p&gt;There is a lot that goes into designing good websites. &lt;a href="http://www.jjg.net/elements/"&gt;The Elements of User Experience&lt;/a&gt; is a great book to read if you want to start at the beginning.&lt;/p&gt;

&lt;h2 id="the-width-and-height-dimensions"&gt;The Width and Height Dimensions&lt;/h2&gt;

&lt;p&gt;Web sites that stretch to fit different browser sizes have been around forever. We’ve called them fluid or liquid layouts for &lt;a href="http://www.westciv.com/style_master/house/good_oil/not_paper/"&gt;over 10 years&lt;/a&gt;. It was always a good idea. The primary thing that has changed is the explosion of mobile. Now fluid layouts are more appealing than ever.&lt;/p&gt;

&lt;p&gt;In that case, what’s actually new here? Responsive Design is the new buzzword, but &lt;a href="http://mediaqueri.es/"&gt;media queries&lt;/a&gt; are the new tech, since they let you serve CSS specific to the situation. Besides that, most of the layout is still being cobbled together using floats, percent-width columns, max-width images, and so on.&lt;/p&gt;

&lt;p&gt;Media queries let you do &lt;a href="https://developer.mozilla.org/en-US/docs/CSS/Media_queries"&gt;a lot of things&lt;/a&gt;. But to be honest, the most important part is checking the viewport width. For example, you can use media queries to show a different number of columns for different screen sizes. &lt;a href="http://learnlayout.com/media-queries.html"&gt;It’s actually super easy&lt;/a&gt;. Well, it’s easy as long as your design process is willing to accommodate it. Think about this from the start: it’s much easier to design a layout where the number of columns can change than it is to take a static layout and figure out how to compress it onto a mobile phone. This is one reason why &lt;a href="http://www.abookapart.com/products/mobile-first"&gt;designing your mobile experience first is such a good idea&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="the-time-dimension"&gt;The Time Dimension&lt;/h2&gt;

&lt;p&gt;Content changes. Even if you’re making a static site for a coffee shop, it’s likely their hours will change, or they’ll start serving breakfast, or they’ll get sued and have to change the “McMuffin” to the “Independently-operated Non-franchise Muffin”.&lt;/p&gt;

&lt;p&gt;Content tends to expand. The web has the convention of vertically-scrolling sites for this reason. There is infinite room to expand vertically when new content is added, just as the site can stretch horizontally when the browser is resized.&lt;/p&gt;

&lt;p&gt;It’s not just about adding new posts to a blog index, though. Your navigation was &lt;a href="http://uxdesign.smashingmagazine.com/2012/03/20/the-elements-of-navigation/"&gt;carefully designed&lt;/a&gt; with the whole of your content in mind, I assume? Every time your content changes, you need to make sure your navigation still makes sense. If you already have “Cocktails” and you’re adding “Beers”, maybe you should consolidate both into “Drinks”. Don’t just add new things wherever there’s space or eventually you’ll get a cluttered mess.&lt;/p&gt;

&lt;p&gt;Part of this is doing the right thing when your content changes. Another part is making a design that can easily accommodate change. For example, lets say you have a menu that is 10em wide. You have to add a new menu item, but the text is longer than 10em. How easy is it to make this work? Do you have to change the CSS in 20 places to make the columns different sizes? Do you end up making the font size smaller to make it fit, despite the fact that the font size was already perfect? A good design is ready to evolve. A stylesheet language like &lt;a href="http://lesscss.org/"&gt;Less&lt;/a&gt; can help you avoid redundancy, which makes the design easier to maintain.&lt;/p&gt;

&lt;h2 id="the-hardware-dimension"&gt;The Hardware Dimension&lt;/h2&gt;

&lt;p&gt;We’re used to varying screen resolutions, but displays are increasingly variable in even more ways. With different pixel densities, aspect ratios, and physical sizes, it has become impractical to design for specific configurations. It’s more important to focus on adaptability in general. Make sure the font sizes are big enough on small screens. Use &lt;a href="https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag"&gt;the viewport meta tag&lt;/a&gt;. Consider scalable graphics with &lt;a href="http://fortawesome.github.io/Font-Awesome/"&gt;icon fonts&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/SVG"&gt;SVG&lt;/a&gt;: these will not pixelate on high density displays, such as Apple’s Retina Display.&lt;/p&gt;

&lt;p&gt;Touch input is a major consideration for mobile, and even some non-mobile displays. It’s important to use large enough touch targets: Microsoft suggests at least &lt;a href="http://msdn.microsoft.com/en-us/library/bb158589.aspx"&gt;38x38&lt;/a&gt;, Apple suggests &lt;a href="https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW1"&gt;44x44&lt;/a&gt;. You don’t have to think of this as chore that’s just for mobile users: &lt;a href="http://uxmovement.com/forms/ways-to-make-checkboxes-radio-buttons-easier-to-click/"&gt;big targets are nice when using a mouse too&lt;/a&gt;. In the end, making sure your UI elements are properly sized will be helpful everywhere.&lt;/p&gt;

&lt;h2 id="the-software-dimension"&gt;The Software Dimension&lt;/h2&gt;

&lt;p&gt;Different browsers, especially different versions of browsers, have different features. The nice thing, though, is that most of these new features were designed to not break the page if the browser doesn’t support them, or if the user turned them off. &lt;a href="http://en.wikipedia.org/wiki/Progressive_enhancement"&gt;Progressive enhancement&lt;/a&gt; is the strategy of starting with the basic content and functionality of a page that works anywhere, then layering on enhanced features when supported. This works for fancy HTML5 application features like &lt;a href="https://github.com/aFarkas/webshim/blob/master/src/shims/geolocation.js"&gt;Geolocation&lt;/a&gt; and &lt;a href="http://socket.io/"&gt;WebSockets&lt;/a&gt;, but it also works for design. &lt;a href="http://css3please.com/"&gt;CSS3&lt;/a&gt; contains a lot of cool new properties for fancy styles, but you should always make sure your site works without them.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://modernizr.com/"&gt;Modernizr&lt;/a&gt; is great for writing CSS that is aware of browser support. It adds classes to the &lt;code&gt;html&lt;/code&gt; element that explain what features are and are not natively supported. You can use these classes in your CSS to write styles specific to different situations.&lt;/p&gt;

&lt;p&gt;The ultimate test of Progressive Enhancement is to view your site with a &lt;a href="http://en.wikipedia.org/wiki/Screen_reader"&gt;screen reader&lt;/a&gt;, or at least with JavaScript and CSS disabled. If it’s still useable, you’re probably on the right track.&lt;/p&gt;

&lt;h2 id="things-that-get-in-the-way"&gt;Things that get in the way&lt;/h2&gt;

&lt;p&gt;By learning to let go, web design can be easier than ever. It’s very Zen, don’t you think? Sure, we’re dealing with more variables than ever, but the technology and tools have improved so much! Let’s look at some things that just get in the way and waste your time.&lt;/p&gt;

&lt;h3 id="it-must-work-on-old-browsers"&gt;It must work on old browsers!&lt;/h3&gt;

&lt;p&gt;Supporting old browsers can make a project take several times as long as it would otherwise. It’s easy to say “We have to support IE7, no matter what!” It’s hard to say “We have to support IE7, even if it takes 8 extra weeks of development time!” Be realistic about what browser support does to your schedule and costs. I’m not saying you should never bother supporting old browsers. I’m saying it’s a tradeoff that requires careful consideration.&lt;/p&gt;

&lt;h3 id="it-must-look-the-same-on-all-platforms"&gt;It must look the same on all platforms!&lt;/h3&gt;

&lt;p&gt;You’ll never get your site to look the same on all platforms. And that’s fine. Remember goal #1: make it easy for people to find and understand your content. Users don’t care if your site looks slightly different in someone else’s browser. If you’re worried about consistency, make sure you can tie that worry to a real objective. How much does it matter? Is it worth the additional development cost?&lt;/p&gt;

&lt;p&gt;Look at platform inconsistency as an opportunity to look and behave in a familiar way. Some input controls look different on different browsers. This reflects the user’s choice to use a certain browser over another, so you should embrace it. In OSX, using touch input, you can scroll the site in a way that shows a gray background “behind” the site. I’ve actually seen people try to prevent this in their web designs. This is part of how the user’s operating system works, it’s what they’re used to, so you should go with the flow.&lt;/p&gt;

&lt;h3 id="pixel-perfection"&gt;Pixel Perfection&lt;/h3&gt;

&lt;p&gt;Pixel perfection doesn’t matter, and is harder than ever. On a 1024x768 display there are 786,432 pixels. On every possible display between 240x320 (&lt;a href="http://en.wikipedia.org/wiki/HTC_Tattoo"&gt;HTC Tattoo&lt;/a&gt;) and 2880x1800 (&lt;a href="http://www.apple.com/macbook-pro/specs-retina/"&gt;Apple 15” MacBook Pro&lt;/a&gt;) there are &lt;a href="http://codepen.io/incompl/pen/aonqk"&gt;6,455,828,464,800&lt;/a&gt;. There are too many pixels. If that menu item is 2 pixels to the left in Firefox, will users have a harder time finding it? If you just focus on the content, you may find that some little tweaks just aren’t that important.&lt;/p&gt;

&lt;h3 id="magic-ratios"&gt;Magic Ratios&lt;/h3&gt;

&lt;p&gt;Did you know the Google homepage is perfect because it uses the &lt;a href="http://en.wikipedia.org/wiki/Golden_ratio"&gt;golden ratio&lt;/a&gt; to achieve ultimate Feng shui? Actually I just made that up. Relying on magical ratios and proportions is superstition. Your web design is a way to display your content, and your content probably doesn’t adhere to a mystical formula. Maybe the number 1.61899 &lt;em&gt;is&lt;/em&gt; particularly beautiful, but don’t prioritize it over your content. If a column needs to be wider to fit the content, just do it.&lt;/p&gt;

&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Design for the web is tricky because there are a lot of variables, and a lot of organizations just aren’t used to the new way of doing things yet. We’re all evolving though, because the web is evolving, and if we keep up, we’re rewarded with an incredible new way to access any information and do anything, anywhere. Even in the &lt;a href="http://www.youtube.com/watch?v=kjxSCAalsBE"&gt;fifth dimension&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/nmAzMMZPel4" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 22 Apr 2013 12:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/the-dimensions-of-web-design</feedburner:origLink></item>
      <item>
        <title>Random Number Generation in JavaScript</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/random-numbers</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/JsYs0bMU_nI/random-numbers</link>
        <author>Adam Hyland</author>
        <description>&lt;p&gt;&lt;a href="http://paulirish.com/"&gt;Paul Irish&lt;/a&gt; recently gave a talk at Bocoup with a dire warning: “&lt;a href="http://www.youtube.com/watch?v=19g4n0ZxiYM"&gt;The Mobile Web is in Trouble&lt;/a&gt;.” The general theme of the talk, somewhat apparent from the title, revolved around developers moving to native apps for performance, capabilities and discoverability. Near the end of the talk he offered a challenge–developers working on the &lt;a href="http://www.w3.org/wiki/Open_Web_Platform"&gt;Open Web&lt;/a&gt; should focus on expanding the capabilities of our apps and the Open Web in general.&lt;/p&gt;

&lt;p&gt;One of the core preserves of native applications is numerical simulation and modeling. &lt;a href="http://en.wikipedia.org/wiki/Numerical_simulation"&gt;Numerical simulation&lt;/a&gt; is commonly used to model and predict the behavior of systems which cannot be modeled analytically or which have a significant random component. Let’s get the core objection out of the way: it’s crazy to perform numerical simulation in JavaScript. There are a half-dozen languages with full featured simulation and modeling capabilities built into the language or well maintained libraries&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;But let’s be crazy. Over the next few weeks I’ll be covering numerical simulation techniques in JavaScript, starting today with an overview of random number generation, then generating normally distributed random variables (along with other distributions) and finally adding in a robust &lt;a href="http://en.wikipedia.org/wiki/Resampling_statistics"&gt;resampling method&lt;/a&gt; to the Miso Project’s &lt;a href="http://misoproject.com/dataset/"&gt;Dataset library&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="whats-the-matter-with-mathrandom"&gt;What’s the matter with Math.random()?&lt;/h2&gt;

&lt;p&gt;JavaScript already has a facility to generate &lt;a href="http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)"&gt;uniformly distributed&lt;/a&gt; random variables: &lt;code&gt;Math.random()&lt;/code&gt;. It seems to cover all our needs, but let’s look at what &lt;a href="http://es5.github.io/x15.8.html#x15.8.2.14"&gt;ES5 has to say&lt;/a&gt; about the expectations for output:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. This function takes no arguments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s not (yet) get hung up on the distinction between random and pseudo-random&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" rel="footnote"&gt;2&lt;/a&gt;&lt;/sup&gt;. The real problematic area is “using an implementation-dependent algorithm or strategy.” Application designers can rely on &lt;code&gt;Math.random()&lt;/code&gt; to provide a black-box of entropy. In that regard it’s pretty good. All of the modern browsers with open source engines use fairly decent random number generators and they’re all pretty fast. Why isn’t that enough?&lt;/p&gt;

&lt;p&gt;Pseudo-random number generators output a long, non-recurring sequence of numbers. The exact value of that sequence is determined by an initial starting value referred to as the “seed”. For any given seed the sequence is apparently random but known and recoverable so long as we know the position and the seed. Each implementation of &lt;code&gt;Math.random()&lt;/code&gt; requires a seed and most seed from the current time or a source of OS randomness (&lt;a href="http://www.cryptography.com/public/pdf/Intel_TRNG_Report_20120312.pdf"&gt;if available&lt;/a&gt;). As the spec indicates, &lt;code&gt;Math.random()&lt;/code&gt; does not accept a seed value from the user and even if it could, the actual generator varies across browsers; Chrome, Firefox, Safari each use different random number generators&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" rel="footnote"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Chrome(v8)&lt;/strong&gt;: Uses a version of the &lt;a href="https://code.google.com/p/chromium/codesearch#chromium/src/v8/src/v8.cc&amp;amp;q=MWC&amp;amp;sq=package:chromium&amp;amp;l=146"&gt;Multiply-with-carry generator&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Firefox (SpiderMonkey)&lt;/strong&gt;: Uses a &lt;a href="http://mxr.mozilla.org/mozilla-central/source/js/src/jsmath.cpp#546"&gt;linear feedback shift generator similar to Java’s&lt;/a&gt;. There &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=322529"&gt;was discussion&lt;/a&gt; to move to the Mersenne Twister but the decision was made to wait until the &lt;a href="http://www.w3.org/TR/WebCryptoAPI/"&gt;Crypto API&lt;/a&gt; was implemented and simply use that.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Safari (JavaScriptCore)&lt;/strong&gt;: Used the Mersenne Twister &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=111533"&gt;until recently&lt;/a&gt;, then switched to a newer generator described &lt;a href="http://dl.acm.org/citation.cfm?id=752741"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can imagine two broad uses for random numbers where an implementation like &lt;code&gt;Math.random()&lt;/code&gt; would be insufficient: simulation and procedurally generated content. Both of these require a generator which is both apparently random and perfectly repeatable.&lt;/p&gt;

&lt;p&gt;A &lt;a href="http://books.google.com/books?id=UXneuOIvhEAC&amp;amp;pg=PA222#v=onepage&amp;amp;q&amp;amp;f=false"&gt;trustworthy simulation&lt;/a&gt; is one where the exact output can be reproduced deterministically. Scientists increasingly depend upon numerical simulation to prove theorems, test systems and inform policy decisions. A seedable random number generator is crucial to reproducibility of those results. But we don’t need to be simulating collisions in the Large Hadron Collider in order to want a means to reproduce our results! If we wrote a physics simulation and wanted users to be able to share their results, it would be physically impossible to do so using &lt;code&gt;Math.random()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Most random number generation in games is perfectly suited to &lt;code&gt;Math.random()&lt;/code&gt;. In general games want a fast source of entropy and don’t need client-side cryptographic strength RNGs. If we want to compute ricochets in a first person shooter, we care a lot about speed and apparent randomness–less so about the period of the generator or our ability to recover the exact numbers generated.&lt;/p&gt;

&lt;p&gt;However if we’re working with procedurally generated content &lt;code&gt;Math.random()&lt;/code&gt; puts us in a bind. We can generate content from the entropy provided but we can’t repeat or share the seed. If we wanted to build a side scroller where players explore procedurally generated landscape and let people play in the same landscape asynchronously, we want to be able to generate identical output for multiple players while storing a minimal amount of state. A seedable random number generator could allow players to share worlds in a web game just easily as they share &lt;a href="http://www.minecraftwiki.net/wiki/Random_seed"&gt;Minecraft seeds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One thing I haven’t mentioned is cryptography. The W3C has a draft &lt;a href="http://www.w3.org/TR/WebCryptoAPI/"&gt;Crypto API&lt;/a&gt; and there are a few good libraries which provide nominally cryptographic strength random number generators (namely &lt;a href="https://code.google.com/p/crypto-js/"&gt;CryptoJS&lt;/a&gt; and the &lt;a href="https://github.com/bitwiseshiftleft/sjcl"&gt;Stanford JavaScript Crypto Library&lt;/a&gt;). But in general we &lt;a href="http://www.matasano.com/articles/JavaScript-cryptography/"&gt;do not&lt;/a&gt; want to do crypto in the browser. No amount of cleverness on the part of a developer can stop a client machine from simply reassigning our random number generator to &lt;code&gt;reallyRandomYouGuys() { return 0.9;}&lt;/code&gt; and &lt;a href="http://www.raphkoster.com/gaming/laws.shtml"&gt;the client is always in the hands of the enemy&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="how-a-random-number-generator-works"&gt;How a random number generator works&lt;/h2&gt;

&lt;p&gt;There are a host of different random number generators, each with their own advantages and (occasionally fatal) flaws. One of the simplest is a &lt;a href="http://en.wikipedia.org/wiki/Linear_congruential_generator"&gt;linear congruential generator&lt;/a&gt; (LCG). It’s predecessor, the &lt;a href="http://en.wikipedia.org/wiki/Lehmer_random_number_generator"&gt;Lehmer generator&lt;/a&gt;, is even simpler but we can explore the LCG a bit to get a feel for how a computer generates random numbers.&lt;/p&gt;

&lt;script src="https://gist.github.com/Protonk/5389384.js"&gt;&lt;/script&gt;

&lt;p&gt;A LCG works by exploiting a relationship between &lt;em&gt;a&lt;/em&gt; (the multiplier), &lt;em&gt;c&lt;/em&gt; (a shifter) and &lt;em&gt;m&lt;/em&gt; (the modulus). The output &lt;em&gt;z&lt;/em&gt; is an integer and serves to seed the next round of the generator. The apparently random numbers are generated by the &lt;a href="http://en.wikipedia.org/wiki/Modulo_operation"&gt;modulus operation&lt;/a&gt; wrapping the value of &lt;code&gt;a * z + c&lt;/code&gt; around &lt;em&gt;m&lt;/em&gt;&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" rel="footnote"&gt;4&lt;/a&gt;&lt;/sup&gt;. Each output &lt;em&gt;z&lt;/em&gt; will range from 0 to &lt;em&gt;m&lt;/em&gt;. A good generator will produce a very long sequence of apparently random numbers. The length of this sequence is referred to as the period of the generator (less commonly, the cycle). A properly configured LCG should have a period equal to its modulus, in this case, 25.&lt;/p&gt;

&lt;script src="https://gist.github.com/Protonk/5389404.js"&gt;&lt;/script&gt;

&lt;p&gt;For longer streams with the same seed this pattern will repeat perpetually. At first this doesn’t seem too useful but if the period of our generator was something like 2^50 (perfectly achievable for some generators) we could generate a million numbers every second from now until 2038 and not run out. Most LCGs of practical values use a very large modulus in order to establish a long period. Unfortunately for us, the period isn’t the only thing which characterizes a random number generator.&lt;/p&gt;

&lt;h2 id="lets-make-some-random-numbers"&gt;Let’s make some random numbers!&lt;/h2&gt;

&lt;script src="https://gist.github.com/Protonk/5367497.js"&gt;&lt;/script&gt;

&lt;p&gt;Don’t worry, they’re not all like this.&lt;/p&gt;

&lt;p&gt;I’ve written a number of implementations of &lt;a href="https://gist.github.com/Protonk/5367430"&gt;standard random number generators in JavaScript&lt;/a&gt;. Each are written in a different style either to match the implementation in the browser (e.g. Chrome’s &lt;a href="http://en.wikipedia.org/wiki/Multiply-with-carry"&gt;MWC&lt;/a&gt; generator or WebKit2’s &lt;a href="http://en.wikipedia.org/wiki/T-function"&gt;invertible mapping generator&lt;/a&gt;) or to expose the basic function of the generator as with the linear congruential generator or the &lt;a href="http://en.wikipedia.org/wiki/Linear_feedback_shift_register"&gt;linear feedback shift generator&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Performance of these generators in the barest sense is actually pretty good. Comparisons with &lt;code&gt;Math.random()&lt;/code&gt; across a number of browsers indicate that most basic generator are &lt;a href="http://jsperf.com/native-and-non-native-random-numbers/5"&gt;relatively competitive&lt;/a&gt;. Also included is David Bau’s &lt;a href="http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html"&gt;ARC4 implementation&lt;/a&gt; as an example of a full featured, robust generator. If your primary goal is not speed and you’re balking at writing a strong random number generator from the ground up, Bau’s implementation is well documented, updated and generally very good. You can see the full source code &lt;a href="http://davidbau.com/encode/seedrandom.js"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Broadly speaking, the lesson is that we don’t lose too much in performance by avoiding native code. So long as we choose our random number generator with a specific purpose in mind, generating robust, reliable sequences in JavaScript should be fast enough for most needs&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" rel="footnote"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h2 id="where-do-we-go-from-here"&gt;Where do we go from here?&lt;/h2&gt;

&lt;p&gt;Over the next few weeks we’ll dig into generating numbers from distributions other than the uniform distribution by a number of methods. If you want a rough preview of what that might involve, you can take a look at &lt;a href="http://blog.yjl.im/2010/09/simulating-normal-random-variable-using.html"&gt;one method for generating normally distributed variables&lt;/a&gt;. We’ll explain how that method works as well as a few others. As we step through creating the building blocks for numerical simulation in JavaScript we’ll also illustrate a few tests for randomness and methods to visualize the performance of a generator.&lt;/p&gt;

&lt;div class="footnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;Basically what &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt; is built for.&lt;a href="#fnref:1" rel="reference"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;Pseudo-random versus random discussion has probably spilled more pointless bits than any debate which didn’t involve a semi-colon.&lt;a href="#fnref:2" rel="reference"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:3"&gt;
      &lt;p&gt;We don’t know about IE or Opera, as their engines aren’t open source.&lt;a href="#fnref:3" rel="reference"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:4"&gt;
      &lt;p&gt;Knuth Volume III offers a rather intensive introduction to the theory behind linear congruential generators as does &lt;a href="http://chagall.med.cornell.edu/BioinfoCourse/PDFs/Lecture4/random_number_generator.pdf"&gt;Hull and Dobell&lt;/a&gt;.&lt;a href="#fnref:4" rel="reference"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:5"&gt;
      &lt;p&gt;Even a native implementation is only about &lt;a href="https://twitter.com/therealprotonk/status/323794069123915777"&gt;6000 times faster&lt;/a&gt; than a Lehmer RNG written for the IBM/360 45 years ago!&lt;a href="#fnref:5" rel="reference"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/JsYs0bMU_nI" height="1" width="1"/&gt;</description>
        <pubDate>Wed, 17 Apr 2013 11:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/random-numbers</feedburner:origLink></item>
      <item>
        <title>Announcing OpenGenderTracker</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/announcing-opengendertracker</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/dTgJmjiPaUo/announcing-opengendertracker</link>
        <author>Cassie Irwin and Irene Ros</author>
        <description>&lt;h2 id="computationally-tracking-gender-balance-in-news-content-with-open-web-technologies"&gt;Computationally Tracking Gender Balance in News Content with Open Web Technologies&lt;/h2&gt;

&lt;p&gt;Last fall, the &lt;a href="http://www.knightfoundation.org/"&gt;Knight Foundation&lt;/a&gt; granted us from the &lt;a href="http://www.knightfoundation.org/funding-initiatives/knight-prototype-fund/"&gt;Prototype Fund&lt;/a&gt; to build &lt;a href="http://opengendertracking.org/"&gt;OpenGenderTracker&lt;/a&gt;, a suite of open source tools for analyzing and visualizing gender representation in journalism through the examination of pronouns in bylines and news content. Bocoupers &lt;a href="http://weblog.bocoup.com/author/irene-ros/"&gt;Irene Ros&lt;/a&gt; and &lt;a href="http://weblog.bocoup.com/author/adam-hyland/"&gt;Adam Hyland&lt;/a&gt; worked with &lt;a href="http://natematias.com/"&gt;Nathan Matias&lt;/a&gt; from the &lt;a href="http://civic.mit.edu"&gt;The MIT Center for Civic Media&lt;/a&gt; to create the tools.&lt;/p&gt;

&lt;p&gt;With this grant, we’ve created an easy-to-deploy, easy-to-integrate service that also provides objective and meaningful metrics. With OpenGenderTracker, publications will be able to efficiently evaluate the voice and gender of content and use this data to inform strategic decision making. Real-time data allow newsrooms to set benchmarks specific to their desks and beats rather than relying on an external organization. Being able to discuss these issues accurately rather than anecdotally will empower modern news organizations to create more compelling stories for their readers.&lt;/p&gt;

&lt;p&gt;The Knight Foundation’s support allowed us to invest in the critical data discovery phase, which is often overlooked in the data visualization process. Dedicating time to thoughtful data discovery builds a strong foundation for more meaningful data visualizations, and the tools the team has built in this phase can now be used by newsrooms to build compelling data visualizations.&lt;/p&gt;

&lt;p&gt;At Bocoup, it is our mission to move the Open Web forward. OpenGenderTracker is an exciting project because it brings more Open Web technology to newsrooms. OpenGenderTracker pushes the diversity issue forward, and diversity on the Open Web makes it more viable. In adopting OpenGenderTracker, newsrooms are further committing to Open Web technologies.&lt;/p&gt;

&lt;p&gt;The newsrooms we are working with praise OpenGenderTracker for providing diversity metrics with actionable tools. Over the next several weeks, we’ll be writing more here about our data discovery phase, our case studies with the Boston Globe and Global Voices, and our future plans and vision for this project.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/dTgJmjiPaUo" height="1" width="1"/&gt;</description>
        <pubDate>Tue, 9 Apr 2013 11:30:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/announcing-opengendertracker</feedburner:origLink></item>
      <item>
        <title>Welcome Corey Frang</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/welcome-corey-frang</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/ThZ32zh99M4/welcome-corey-frang</link>
        <author>Cassie Irwin</author>
        <description>&lt;p&gt;We’re excited to announce that our friend and colleague &lt;a href="http://gnarf.net/"&gt;Corey Frang&lt;/a&gt; has joined us at Bocoup.&lt;/p&gt;

&lt;p&gt;Corey is a talented programmer and computer scientist who has long been a contributor to open source technologies. As a jQuery core committer, Corey led the &lt;a href="http://api.jquery.com/category/effects/"&gt;jQuery Effects&lt;/a&gt; rewrite, and currently serves on the &lt;a href="https://jquery.org/team/"&gt;jQuery Foundation Board of Directors&lt;/a&gt;. We deeply respect Corey’s experience and passion for engineering, and look forward to working with him to bring his talents to our projects.&lt;/p&gt;

&lt;p&gt;Be sure to follow Corey on &lt;a href="https://twitter.com/gnarf37"&gt;Twitter&lt;/a&gt; and on &lt;a href="https://github.com/gnarf37"&gt;GitHub&lt;/a&gt;, or say hello to gnarf in the #bocoup channel on the &lt;a href="https://webchat.freenode.net/"&gt;freenode irc network&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/ThZ32zh99M4" height="1" width="1"/&gt;</description>
        <pubDate>Thu, 4 Apr 2013 11:30:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/welcome-corey-frang</feedburner:origLink></item>
      <item>
        <title>Welcome Brendan McLoughlin</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/welcome-brendan-mcloughlin</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/7CuJvVpzIJs/welcome-brendan-mcloughlin</link>
        <author>Cassie Irwin</author>
        <description>&lt;p&gt;We’re happy to announce that &lt;a href="http://www.brendanmcloughlin.com"&gt;Brendan McLoughlin&lt;/a&gt; has joined Bocoup as a member of our consulting team.&lt;/p&gt;

&lt;p&gt;Brendan is an Open Web programmer with full-stack web development experience, who impressed us with his contribitions to open source projects including &lt;a href="http://github.com/SteveSanderson/knockout/issues/170"&gt;knockout.js&lt;/a&gt; and &lt;a href="http://github.com/bmac/audioPromise"&gt;audioPromise&lt;/a&gt;. Commitment to open technologies is paramount at Bocoup - we’re excited that Brendan shares this interest and can’t wait to see where he’ll contribute next!&lt;/p&gt;

&lt;p&gt;We’re eager to move the Open Web forward with Brendan. Follow him on &lt;a href="http://twitter.com/BezoMaxo"&gt;Twitter&lt;/a&gt; and on &lt;a href="http://github.com/bmac"&gt;GitHub&lt;/a&gt;, and be sure to stop by our &lt;a href="http://www.meetup.com/javascript-2/"&gt;next JavaScript meetup&lt;/a&gt; to talk with Brendan about his knockout.js work or have him explain just exactly what skimboarding is!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/7CuJvVpzIJs" height="1" width="1"/&gt;</description>
        <pubDate>Wed, 3 Apr 2013 12:20:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/welcome-brendan-mcloughlin</feedburner:origLink></item>
      <item>
        <title>Learn CSS Layout Meets Latin America</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/learn-css-layout-meets-latin-america</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/GJBhD6N2TEg/learn-css-layout-meets-latin-america</link>
        <author>Isaac Durazo</author>
        <description>&lt;p&gt;Last week I translated &lt;a href="http://weblog.bocoup.com/author/greg-smith/"&gt;Greg Smith’s&lt;/a&gt; &lt;a href="http://learnlayout.com"&gt;Learn CSS Layout&lt;/a&gt; into Spanish in an effort to bring this amazing guide to more people around the world.&lt;/p&gt;

&lt;p&gt;When I was in college, Spanish-language resources for learning about new Web Design technologies were very limited. Not only was finding them difficult, but the resources were also frequently out of date. Often, the best option was to read English-language tutorials with a dictionary at hand, all that while shaking my fist in frustration. Forcing myself to read and watch videos in a foreign language is how I learned most of what I now know about the world of Web Development - and English.&lt;/p&gt;

&lt;p&gt;When I first saw &lt;a href="http://learnlayout.com"&gt;Learnlayout.com&lt;/a&gt;, I was struck by how useful a site like this would have been for me when I started to learn HTML and CSS. This gave me the idea of translating the site into Spanish. I wanted to share this with people from Latin America who want to learn, but simply because of the language barrier, can’t find the right place to do it.&lt;/p&gt;

&lt;p&gt;Learn CSS Layout is one of the best guides out there, and now it has a Spanish version. And not only that, someone &lt;a href="https://github.com/incompl/csslayoutsite/pull/42"&gt;landed a pull request&lt;/a&gt; for a Farsi version last week, and even more people are working on Portuguese, French, Chinese, German and Russian translations. Isn’t that awesome?&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://github.com/incompl/csslayoutsite/blob/master/README.textile"&gt;instructions in the readme&lt;/a&gt; for translations. If you’d like to work on one, &lt;a href="https://github.com/incompl/csslayoutsite/issues"&gt;let us know in the project issue tracker&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Part of the Open Web mission is open access. Making resources like Learn CSS Layout more accessible to a wide and diverse audience, including non-English speakers, is very on mission for Bocoup and important for me in my work here. We can only move the Open Web forward if we move it forward for everyone.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/GJBhD6N2TEg" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 25 Mar 2013 14:09:08 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/learn-css-layout-meets-latin-america</feedburner:origLink></item>
      <item>
        <title>Welcome K.Adam White</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/welcome-kadam-white</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/LQIxexlarSI/welcome-kadam-white</link>
        <author>Cassie Irwin</author>
        <description>&lt;p&gt;A few weeks ago, Bocoup announced a &lt;a href="http://workat.bocoup.com"&gt;casting call for our Open Web stand-up comedy troupe&lt;/a&gt;. &lt;a href="http://www.kadamwhite.com/"&gt;K.Adam White&lt;/a&gt; heard our call, impressed us with his impeccable comedic delivery, and has joined our team this week!&lt;/p&gt;

&lt;p&gt;K.Adam (pronounced “KAdam”) comes to Bocoup by way of Grand Circle Corporation, where he was the lead front end developer. He brings extensive experience in UI design and implementation to Bocoup. KAdam has also been active in the local WordPress community since 2008, and recently became one of the co-organizers of the &lt;a href="http://meetup.bostonwp.org/"&gt;local meetup group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are so excited to have KAdam on the team, and look forward to creating amazing things with him. Follow KAdam on Twitter at &lt;a href="http://www.twitter.com/kadamwhite"&gt;@kadamwhite&lt;/a&gt; and on &lt;a href="http://github.com/kadamwhite"&gt;GitHub&lt;/a&gt;. When you’re at our &lt;a href="http://loft.bocoup.com/"&gt;next meetup&lt;/a&gt;, be sure to get his favorite taco recipe (hint: it involves pickled cabbage!)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/LQIxexlarSI" height="1" width="1"/&gt;</description>
        <pubDate>Tue, 19 Mar 2013 11:30:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/welcome-kadam-white</feedburner:origLink></item>
      <item>
        <title>Getting Started with Mozilla Gaia</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/getting-started-with-mozilla-gaia</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/1U4j8r1ynd4/getting-started-with-mozilla-gaia</link>
        <author>Dan Heberden</author>
        <description>&lt;p&gt;Mozilla recently announced &lt;a href="http://www.mozilla.org/en-US/firefox/partners/#os"&gt;FirefoxOS&lt;/a&gt;, an innovative  project for mobile devices that uses Open Web standards to write UI and applications in HTML, CSS, and JavaScript. The team at Mozilla has done an incredible amount of work connecting a version of Gecko made specifically for the mobile operating system, to &lt;a href="https://github.com/mozilla-b2g/gaia"&gt;Gaia&lt;/a&gt;, the web technology-driven UI of the phone. They’ve also been working to create a full suite of applications to drive the capabilities of the phone. &lt;/p&gt;

&lt;p&gt;The Mozilla Gaia project makes the Open Web a first-class citizen on mobile phones - an important endeavor considering that mobile is the only option in many parts of the world. We’re incredibly excited to join this project, and to augment the Mozilla team’s work with our expertise in solid application architecture, unit tests, and developer workflow. Our early work focused on getting acquainted with the project, improving the test suite, and digging into bug fixes and code review processes. As a set of fresh eyes on the project, this time allowed us to see possible pain points for new developers who want to build or work on Gaia, and create good documentation for developers new to working in Gaia. &lt;/p&gt;

&lt;p&gt;In our &lt;a href="https://github.com/bocoup/gaia-notes"&gt;gaia-notes repo&lt;/a&gt;, you can find documentation for getting started, debugging Gaia on desktop B2G, and building your first app. &lt;a href="http://weblog.bocoup.com/author/mike-pennisi/"&gt;Mike Pennisi&lt;/a&gt; has also created a screencast to walk developers through getting started with the Gaia project. These resources have already proven very helpful to those involved with the project, and we’re looking forward to adding to the documentation and helping this project grow.&lt;/p&gt;

&lt;iframe src="http://fast.wistia.net/embed/iframe/q3qlfm54bh?controlsVisibleOnLoad=true&amp;amp;version=v1&amp;amp;videoHeight=338&amp;amp;videoWidth=600" allowtransparency="true" frameborder="0" scrolling="no" class="wistia_embed" name="wistia_embed" width="600" height="338"&gt;&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/1U4j8r1ynd4" height="1" width="1"/&gt;</description>
        <pubDate>Tue, 5 Mar 2013 01:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/getting-started-with-mozilla-gaia</feedburner:origLink></item>
      <item>
        <title>Learn CSS Layout</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/introducing-learnlayout</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/0X3-V_Z1Fxc/introducing-learnlayout</link>
        <author>Greg Smith</author>
        <description>&lt;p&gt;&lt;img style="float:right;margin:0 0 1em 1em;" src="http://bocoup.com//img/weblog/learnlayout.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://learnlayout.com"&gt;Learn CSS Layout&lt;/a&gt; is a new learning and reference site I made in my open source time here at Bocoup. Although there are lots of resources on the web for learning CSS layout techniques, we’ve had trouble finding ones we’re comfortable recommending. &lt;a href="http://learnlayout.com"&gt;Learnlayout.com&lt;/a&gt; is an enlightening and accessible look at modern techniques for beginners, while also being a useful reference for more advanced developers. The site also features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Functional and flexible examples&lt;/li&gt;
  &lt;li&gt;A start-to-finish narrative&lt;/li&gt;
  &lt;li&gt;Pages that are useful as stand-alone references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://learnlayout.com"&gt;Take a look&lt;/a&gt;, and if you have any feedback or suggestions, &lt;a href="https://github.com/incompl/csslayoutsite/issues?state=open"&gt;let me know on Github&lt;/a&gt;!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/0X3-V_Z1Fxc" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 4 Mar 2013 12:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/introducing-learnlayout</feedburner:origLink></item>
      <item>
        <title>Open Source Everything: Working with the jQuery Foundation</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/open-source-everything-working-with-jquery-foundation</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/33-_hqb-nyY/open-source-everything-working-with-jquery-foundation</link>
        <author>Adam J. Sontag</author>
        <description>&lt;p&gt;One of the awesome things about being a Bocouper is being able to use a quarter
of your time to explore and work on open source. Whether it’s just trying out
new tools or regularly contributing to a large project, it’s a great way for us
to improve and give back to the technologies we use and teach. Sometimes, we
find that a project’s goals align so closely with our own that we go above and
beyond that threshold to provide even more support.&lt;/p&gt;

&lt;p&gt;Over the past few months, I’ve been able to spend a great deal of time working
on the &lt;a href="http://blog.jquery.com/2013/01/23/a-site-to-behold-open-content-design-comes-to-jquery-2/"&gt;jQuery Foundation’s initiative to open source the content and design of
all its
sites&lt;/a&gt;.
A major reason for this effort is to dramatically lower the barrier for
community involvement and therefore open up entirely new avenues for people
who’d like to begin helping out, but haven’t been sure how.&lt;/p&gt;

&lt;p&gt;Throughout our experiences teaching classes and working with clients on
consulting projects, many of us have noticed that newcomers face a double
challenge when trying to get started with open source. This is because of the
combination of needing to learn new tools while also searching to find bugs
that they’re actually capable of solving (that haven’t already been swept up by
the project’s maintainers). This lack of fodder can limit the opportunities to
gain experience, and ultimately many end up demoralized and commit-less.&lt;/p&gt;

&lt;p&gt;That’s why I’m so excited about the work we’ve done at the jQuery Foundation to
apply the same workflows that we use when developing JavaScript libraries to
documentation and design. There have always been a lot of ways to contribute to
jQuery beyond writing code, but many of them required special permission to
access and offered nothing but a &lt;code&gt;textarea&lt;/code&gt; when you got there. With the new
system we have in place, anyone can report an issue or propose a fix (from the
comfort of their favorite text editor) simply by sending a pull request, and
updating our sites is as simple as pushing a commit to &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s good news for people who are already good at using git and GitHub, but
it’s also good news for folks who have been hesitant to try them out. You don’t have to
“reproduce” a typo, nor do you have to write unit tests for a new paragraph of
documentation. So if you “just use a little bit” of jQuery but always thought
you’d never have anything you’d be able to contribute back, it’s definitely
time to think again! Or if you have been searching for an open source project
where you can have a significant impact while you still learn to flex your git muscles,
consider yourself at home!&lt;/p&gt;

&lt;p&gt;To learn more about the technologies involved and find out how it all works,
take a look at the &lt;a href="http://contribute.jquery.org/web-sites/#how-it-works"&gt;jQuery Foundation’s web site contribution guide&lt;/a&gt;.
The new &lt;a href="http://learn.jquery.com"&gt;jQuery Learning Center&lt;/a&gt; is especially ripe territory
for anyone who likes helping other people out and has good ideas to share!&lt;/p&gt;

&lt;p&gt;I’m thrilled to have had Bocoup’s support implementing this new stack, and I’m
proud to have had a part in bringing things to where they are today. It’s been
an amazing ride thus far, and I’m looking forward to watching the sites evolve
as more developers join us in improving themselves, each other, and the
entire Open Web.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/33-_hqb-nyY" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 25 Feb 2013 16:20:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/open-source-everything-working-with-jquery-foundation</feedburner:origLink></item>
      <item>
        <title>Ember.js Training from Tilde at Bocoup</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/ember-training-with-tilde</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/1YRn7LOy6XY/ember-training-with-tilde</link>
        <author>Jory Burson</author>
        <description>&lt;p&gt;We’re so excited that our friends &lt;a href="https://github.com/wycats"&gt;Yehuda Katz&lt;/a&gt; and &lt;a href="https://github.com/tomdale"&gt;Tom Dale&lt;/a&gt; from &lt;a href="http://www.tilde.io/"&gt;Tilde&lt;/a&gt; will be stopping by the Bocoup Loft to deliver &lt;a href="http://www.tilde.io/events/introduction-to-ember-public/#event-tickets"&gt;Introduction to Ember training&lt;/a&gt; April 22-24.&lt;/p&gt;

&lt;p&gt;At Bocoup, we support a wide variety of Open Web technologies. We believe in the right tool for the job, so we’re actively exploring different MV* libraries and frameworks. That’s why we’re happy to support Ember.js training in addition to hosting &lt;a href="http://training.bocoup.com/building-web-applications-with-backbone/"&gt;Backbone.js trainings&lt;/a&gt; and &lt;a href="http://www.meetup.com/backbonejs/"&gt;meetups&lt;/a&gt;, and the newly-formed &lt;a href="http://www.meetup.com/AngularJS-Boston/"&gt;Angular.js meetup&lt;/a&gt; for the Boston development community. If you’re looking to learn more about Ember.js, we hope to see you there!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/1YRn7LOy6XY" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 25 Feb 2013 01:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/ember-training-with-tilde</feedburner:origLink></item>
      <item>
        <title>Making a RapBot with JavaScript</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/making-a-rapbot</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/EFF3Fv7k_WA/making-a-rapbot</link>
        <author>Darius Kazemi</author>
        <description>&lt;p&gt;This post talks about the development of RapBot, my freestyle 80s battle rap generator. You might want to &lt;a href="http://rapbot.jit.su"&gt;see it in action&lt;/a&gt; before reading on, and you can &lt;a href="https://github.com/dariusk/rapbot"&gt;check out the source code here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the past year I’ve been using &lt;a href="http://developer.wordnik.com/docs"&gt;the Wordnik API&lt;/a&gt; in my projects to generate random words. I’ve made extensive use of their &lt;code&gt;randomWords&lt;/code&gt; feature in projects like &lt;a href="http://tinysubversions.com/allthethings"&gt;All the Things&lt;/a&gt;, &lt;a href="http://twitter.com/metaphorminute"&gt;Metaphor-a-Minute!&lt;/a&gt;, and even &lt;a href="http://randomshopper.tumblr.com"&gt;Amazon Random Shopper&lt;/a&gt; but for every project I’d copy/paste code for interfacing with Wordnik. I’d been meaning to write my own interface to the API, but I’d been putting it off, because, well, I’m lazy. But a couple of weeks ago I took our &lt;a href="http://training.bocoup.com/building-web-applications-with-backbone/"&gt;Building Web Applications with Backbone&lt;/a&gt; class, and I was finally inspired to build a promises-based interface to Wordnik using Backbone, which I called &lt;a href="http://github.com/dariusk/wordnik-bb"&gt;wordnik-bb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was while building my library that I noticed that Wordnik had recently added rhyming to their API! That is, you can send an English word to their &lt;a href="http://developer.wordnik.com/docs#!/word/get_related_words"&gt;relatedWords API call&lt;/a&gt; and it’ll send you back an array of words that rhyme with it. I had never really played with the power of their powerful semantic “word graph” before and now I finally had an excuse to do so.&lt;/p&gt;

&lt;h2 id="experimenting-with-creative-code"&gt;Experimenting with creative code&lt;/h2&gt;

&lt;p&gt;Whenever I start a creative coding exercise, I do some simple prototyping to see if the core idea I have posesses any potential to be interesting. Initially I just brute forced a few API calls using the excellent interactive tools over at &lt;a href="http://developer.wordnik.com/docs"&gt;the Wordnik API documentation&lt;/a&gt;. I wrote the first thing that came to mind:&lt;/p&gt;

&lt;script src="https://gist.github.com/dariusk/4979315.js"&gt;&lt;/script&gt;

&lt;p&gt;I was pretty happy with the output of this. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;I once knew someone who was Iraqi
Their manners were very wacky
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;My rule of thumb for creative coding is: if it makes me laugh, it’s probably worth pursuing.&lt;/p&gt;

&lt;p&gt;At any rate, I showed this to my friend &lt;a href="http:/thiscageisworms.com"&gt;Cameron Kunzelman&lt;/a&gt; and he immediately responded, “So basically you’re telling me this rhyming machine is going to be able to make late 1980s rap pretty consistently.” This reminded me that I’d wanted to make a “bad freestyle rapper” bot for &lt;em&gt;ages&lt;/em&gt;, and now I had the means to do so.&lt;/p&gt;

&lt;p&gt;One equation for making a cool textual generator is: &lt;strong&gt;&lt;em&gt;randomness + formulaic writing = hilarity&lt;/em&gt;&lt;/strong&gt;. So I pretty quickly realized that having my program generate a battle rap was the way to go. A good resource for this is Adam Bradley’s &lt;em&gt;&lt;a href="http://www.amazon.com/Book-Rhymes-Poetics-Hip-Hop/dp/0465003478"&gt;Book of Rhymes: The Poetics of Hip Hop&lt;/a&gt;&lt;/em&gt;, which lays out some of the formula behind battle rhymes.&lt;/p&gt;

&lt;h2 id="battles-are-better-with-promises"&gt;Battles are better with promises&lt;/h2&gt;

&lt;p&gt;The basic algorithm for RapBot has remained the same from the start:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Get a random word and its part of speech. Get a ‘line’ for that word based on the part of speech. For example if it’s a noun, it’ll pick from a bunch of noun lines, like “I’m the illest MC to ever rock the [noun]”&lt;/li&gt;
  &lt;li&gt;Once I have that first word, get a list of words that rhyme with it. (Wordnik is sort of inconsistent. Some words just lack any rhyme data.)&lt;/li&gt;
  &lt;li&gt;If I get back any rhyming words, then I pick one at random and also get its part of speech.&lt;/li&gt;
  &lt;li&gt;Much like I did with the first word, I get a line to match its part of speech.&lt;/li&gt;
  &lt;li&gt;Now I have a couplet! I repeat this 12 times, which will get us anywhere from 0 (if it couldn’t find rhymes for any words at all, a rare case) to 12 couplets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This algorithm would have been a lot harder to write if I weren’t using a promises implementation. If you’re not familiar with promises, &lt;a href="http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/"&gt;here’s an introduction to jQuery’s implementation of promises&lt;/a&gt;. The short version is: if you’re making asynchronous calls to a service (like I’m doing with Wordnik), you can’t be guaranteed when you’ll get the data back. It could be in 200ms, or 2 seconds, or 20 seconds. So instead of writing a function that returns a value like the part of speech for a word, you write a function that returns a &lt;em&gt;promise&lt;/em&gt; for the part of speech of a word. Then you can define callbacks on the promise telling it what to do if it’s resolved as a success, rejected as a failure, etc. &lt;/p&gt;

&lt;p&gt;So now that you’re an expert on promises (&lt;em&gt;cough&lt;/em&gt;), you can now see that an algorithm where it says “make this async call, then when that’s done make that async call” and chains it a bunch of times is a great place for us to use promises. &lt;/p&gt;

&lt;p&gt;Here’s an example of promises in RapBot, when we ask the Wordnik API for a part of speech of a word:&lt;/p&gt;

&lt;script src="https://gist.github.com/dariusk/4979633.js"&gt;&lt;/script&gt;

&lt;p&gt;Compare this to the structure of the &lt;code&gt;getLine&lt;/code&gt;, which is a good ol’ synchronous function:&lt;/p&gt;

&lt;script src="https://gist.github.com/dariusk/4979533.js"&gt;&lt;/script&gt;

&lt;h2 id="reducing-api-calls"&gt;Reducing API calls&lt;/h2&gt;

&lt;p&gt;I did a “soft launch” of RapBot on a Saturday night to see how it would perform. The answer: not terribly well. Wordnik’s API caps the number of calls per hour at 5000 calls. That might seem like a lot, but at the time of my soft launch, every page load made somewhere close to 50 API calls! That’s because each couplet would:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Get a random word (1 API call)&lt;/li&gt;
  &lt;li&gt;Get the part of speech for it (1 API call)&lt;/li&gt;
  &lt;li&gt;Get a list of words that rhyme with it (1 API call)&lt;/li&gt;
  &lt;li&gt;Pick a word from that list (not an API call)&lt;/li&gt;
  &lt;li&gt;Get the part of speech for it (1 API call)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So each couplet is 4 API calls, and for 12 couplets that could be as many as 48 API calls.&lt;/p&gt;

&lt;p&gt;Fortunately, I was able to get the number of API calls down to about 29 from 48. In addition to returning individual random words, Wordnik can also &lt;a href="http://developer.wordnik.com/docs#!/words/get_random_words"&gt;return an array of up to 1000 random words&lt;/a&gt; in a single API call. You can also ask for an array of random words of a particular part of speech. Looking at the first two steps of creating a couplet, you can see that I’m getting a word and getting its part of speech. The better approach would be: on page load, grab an array of random words for each part of speech that I need. Since I support 5 parts of speech, that’s 5 API calls. Then in each couplet I say: pick one of our parts of speech we support, then access the array of words for it. This means that the couplet algorithm now looks like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pick one of our five parts of seech (not an API call)&lt;/li&gt;
  &lt;li&gt;Get a word from the array of random words from that part of speech (not an API call)&lt;/li&gt;
  &lt;li&gt;Get a list of words that rhyme with it (1 API call)&lt;/li&gt;
  &lt;li&gt;Pick a word from that list (not an API call)&lt;/li&gt;
  &lt;li&gt;Get the part of speech for it (1 API call)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So now each couplet is only 2 API calls, which means that the 12 couplets make 24 API calls total. Add in the 5 API calls on page load and we’re now down to 29 calls from 48. (As often happens with refactoring for performance, my code became more modular and suddenly I was able to tweak the frequency of appearance of each part of speech. So now I can say: give me a noun 40% of the time, an adverb 10% of the time, etc.)&lt;/p&gt;

&lt;p&gt;There’s further work that could be done. Instead of making the 5 API calls on page load, the application could make the 5 API calls on startup and store it globally on the server. But that would reduce the variety of results on each page load. I could increase the randomness by updating those random word arrays silently in the background, making the API calls once every half hour, and appending the results to the existing arrays.&lt;/p&gt;

&lt;p&gt;Beyond that I could cache a whole bunch of couplets and just refer to the cached results on every page load, but again that would further reduce the randomness of the results and make the whole exercise less fun.&lt;/p&gt;

&lt;p&gt;I do have to give a shout-out to the team at Wordnik for increasing my API call limit, too!&lt;/p&gt;

&lt;h2 id="looking-ahead"&gt;Looking ahead&lt;/h2&gt;

&lt;p&gt;With any creative coding project there will always be a long list of ways to improve. Potential improvements include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;More complicated rhyme schemes&lt;/li&gt;
  &lt;li&gt;Bots that respond to each other (1: “You’re nothing but a [noun1]!” 2: “You call me a [noun1]? You’re just a [noun2]!”)&lt;/li&gt;
  &lt;li&gt;Take meter into account, so the rhymes scan right&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these things will result in more API calls, so before I do anything else, the next step would involve caching results to reduce API calls by an order of magnitude to something like 2 or 3 per page.&lt;/p&gt;

&lt;p&gt;In closing, I leave you with some cryptic words of wisdom about the Open Source ecosystem, courtesy of RapBot:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;If you're gonna battle me, then you gotta be noncommercial 
When I rock a mic you know I rock it real uncontroversial
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/EFF3Fv7k_WA" height="1" width="1"/&gt;</description>
        <pubDate>Wed, 20 Feb 2013 15:33:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/making-a-rapbot</feedburner:origLink></item>
      <item>
        <title>Tearing Grunt Apart</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/tearing-grunt-apart</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/QbIIwUsrse0/tearing-grunt-apart</link>
        <author>Tyler Kellen and Ben Alman</author>
        <description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/2dfa93e54912cd2e9b2506079879ff26.jpg" style="float: left; margin: 5px 10px 10px 10px;" /&gt;
&lt;em&gt;This is a guest post by &lt;a href="http://tkellen.com"&gt;Tyler Kellen&lt;/a&gt;, who co-maintains Grunt with &lt;a href="http://benalman.com/"&gt;Ben Alman&lt;/a&gt;, and is also the project lead for the officially curated &lt;a href="http://github.com/gruntjs/"&gt;contrib&lt;/a&gt; series of grunt plugins.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id="introducing-grunt-v04"&gt;Introducing Grunt v0.4&lt;/h3&gt;
&lt;p&gt;For the last nine months, I’ve been working with Ben and &lt;a href="https://github.com/gruntjs?tab=members"&gt;our team of fantastic contributors&lt;/a&gt; to modularize the Grunt codebase. Today, we’re happy to announce that Grunt v0.4 has been published to npm. Hold on to your hats, a lot has changed!&lt;/p&gt;

&lt;h3 id="architectural-improvements"&gt;Architectural Improvements&lt;/h3&gt;
&lt;p&gt;The primary focus of this version can be summarized by the venerable words of &lt;a href="http://en.wikipedia.org/wiki/Douglas_McIlroy"&gt;Doug McIlroy&lt;/a&gt;, “Do one thing and do it well.” We’re proud to say that this release is a major milestone on the road to fully embracing &lt;a href="http://en.wikipedia.org/wiki/Unix_philosophy"&gt;the Unix philosophy&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id="built-in-tasks-removed"&gt;Built In Tasks Removed&lt;/h4&gt;
&lt;p&gt;If you’re coming from Grunt v0.3.x, the most immediate difference you’ll notice is that we’ve removed all of the built-in tasks. Don’t worry, they aren’t gone—we’ve extracted them into officially maintained, standalone plugins. If you visit the &lt;a href="http://gruntjs.com/plugins"&gt;plugin listing&lt;/a&gt; on our website, look for the entries with stars next to their names.&lt;/p&gt;

&lt;p&gt;One of the biggest benefits of this change is faster iteration.  It’s no longer necessary to ship a new version of Grunt for every minor plugin change!  If &lt;a href="http://jshint.com/"&gt;jshint&lt;/a&gt; gets updated, for example, we can just release a new version of &lt;a href="https://github.com/gruntjs/grunt-contrib-jshint"&gt;grunt-contrib-jshint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, with our core plugins separated, the barrier to entry for collaboration is lower than ever. If you’d like to get involved, please join us in &lt;a href="irc://irc.freenode.net/#grunt"&gt;#grunt on irc.freenode.net&lt;/a&gt;, or check out the &lt;a href="http://gruntjs.com/contributing"&gt;Contributing guide&lt;/a&gt; and submit a pull request to add the feature you want.&lt;/p&gt;

&lt;h5 id="a-note-about-the-init-task"&gt;A note about the “init” task&lt;/h5&gt;
&lt;p&gt;This scaffolding task was always an odd-duck, and it really deserves it’s own project.  So, we’ve broken it into a separate npm module, &lt;a href="http://github.com/gruntjs/grunt-init"&gt;grunt-init&lt;/a&gt;, which can be installed globally with &lt;code&gt;npm install -g grunt-init&lt;/code&gt;.  In the coming weeks, the &lt;a href="http://yeoman.io"&gt;Yeoman&lt;/a&gt; team will be replacing this task entirely, using their &lt;a href="https://github.com/yeoman/generator"&gt;rails-inspired generator system&lt;/a&gt;. If you’ve authored templates for the init task, get in touch with &lt;a href="http://github.com/yeoman/?tab=members"&gt;them&lt;/a&gt; for details on how to make the conversion.&lt;/p&gt;

&lt;h4 id="global-installation"&gt;Global Installation&lt;/h4&gt;

&lt;p&gt;Another departure for those coming from Grunt v0.3.x is that Grunt itself no longer ships with a binary. Instead of installing Grunt globally, you now specify it as a development dependency in your project’s package.json file, along with any Grunt plugins you might be using.&lt;/p&gt;

&lt;p&gt;In order to get the &lt;code&gt;grunt&lt;/code&gt; command, we’ve provided the &lt;a href="http://github.com/gruntjs/grunt-cli"&gt;grunt-cli&lt;/a&gt; tool, which should be installed globally. The sole purpose of this tool is to load and run the locally installed version of Grunt, and good news—it will work with every version from 0.3x and higher.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There has been considerable confusion in the community about global vs local installation of packages. We recommend reading &lt;a href="http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation"&gt;this excellent article&lt;/a&gt; by &lt;a href="http://github.com/isaacs"&gt;@isaacs&lt;/a&gt; for more information about why it is desirable to install things locally when using node.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id="supercharging-grunts-declarative-power"&gt;Supercharging Grunt’s Declarative Power&lt;/h3&gt;
&lt;p&gt;Gruntfiles are now more powerful than ever. We’ve been hard at work implementing community requests, and thanks to everyone’s feedback, the results are fantastic.  Here are a few of the major additions:&lt;/p&gt;

&lt;h4 id="options-merging"&gt;Options Merging&lt;/h4&gt;
&lt;p&gt;Need to run the same task on more than one set of files?  Say goodbye to duplicative configuration, options can now be defined at the task level—they’ll automatically apply for all of your target file groups. If needed, you can override them individually. &lt;a href="http://gruntjs.com/configuring-tasks#options"&gt;Check out our documentation for more details.&lt;/a&gt;&lt;/p&gt;

&lt;h4 id="mapping-individual-files-from-one-location-to-another"&gt;Mapping individual files from one location to another&lt;/h4&gt;
&lt;p&gt;We have a new syntax for this common request (e.g. compiling coffeescript files from one directory to javascript files in another, while maintaining the folder structure), it works with any v0.4 compatible plugin, and it eliminates reams of boilerplate for plugin authors. &lt;a href="http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically"&gt;Check out our documentation for more details.&lt;/a&gt;&lt;/p&gt;

&lt;h4 id="templates-everywhere"&gt;Templates everywhere&lt;/h4&gt;
&lt;p&gt;Need data from &lt;code&gt;package.json&lt;/code&gt; for your build process? How about a YAML file?  Not a problem, just load it into your configuration and apply it anywhere you like. &lt;a href="http://gruntjs.com/configuring-tasks#importing-external-data"&gt;Check out our documentation for more details.&lt;/a&gt;&lt;/p&gt;

&lt;h3 id="new-apis"&gt;New APIs&lt;/h3&gt;
&lt;p&gt;Just to whet your whistle, here are a few handy methods we’ve added to make writing tasks a cinch: &lt;a href="http://gruntjs.com/api/grunt.file#grunt.file.ispathincwd"&gt;file.isPathInCwd&lt;/a&gt;, &lt;a href="http://gruntjs.com/api/grunt.file#grunt.file.doespathcontain"&gt;file.doesPathContain&lt;/a&gt; &amp;amp; &lt;a href="http://gruntjs.com/api/grunt.file#grunt.file.arepathsequivalent"&gt;file.arePathsEquivalent&lt;/a&gt;. There are far too many additions to list in this introduction, &lt;a href="http://gruntjs.com/upgrading-from-0.3-to-0.4#api"&gt;please see our migration documentation&lt;/a&gt; for a full rundown.&lt;/p&gt;

&lt;h3 id="new-website"&gt;New Website&lt;/h3&gt;
&lt;p&gt;Grunt 0.4 ships with a flashy new website.  We’ve got reams of documentation, and helpful tools for discovering the perfect plugin for your project.  Check it out at &lt;a href="http://gruntjs.com"&gt;gruntjs.com&lt;/a&gt;!&lt;/p&gt;

&lt;h3 id="roadmap"&gt;Roadmap&lt;/h3&gt;
&lt;p&gt;If you think Grunt is great now, just wait until you see what we have in store for the next major version. Here’s a glimpse of what you can expect next:&lt;/p&gt;

&lt;h4 id="glob-expansion-library"&gt;Glob Expansion Library&lt;/h4&gt;
&lt;p&gt;Grunt has made it easier than ever to select, negate and map your project files from one location to another—complicated globbing patterns need not apply!  We’re so happy with the power this system affords that we’re going to extract it into a standalone library so anyone can use it.&lt;/p&gt;

&lt;h4 id="configuration-library"&gt;Configuration Library&lt;/h4&gt;
&lt;p&gt;Sharing values across multiple configuration files is a breeze with Grunt’s templating system. Soon, you’ll be able to unleash Grunt’s declarative power anywhere you need it—we’re turning this system to a standalone npm package as well.&lt;/p&gt;

&lt;h4 id="grunt-middleware"&gt;Grunt Middleware&lt;/h4&gt;
&lt;p&gt;Don’t like Grunt’s configuration syntax? Go crazy and write a middleware to convert your format to ours. Maybe we’ll love it and decide to make it the default.&lt;/p&gt;

&lt;h4 id="escaping-dependency-hell"&gt;Escaping Dependency Hell&lt;/h4&gt;
&lt;p&gt;When you upgrade to v0.4, chances are strong you’ll run into some tasks that don’t support it yet. We know this sucks, and we’re working with plugin authors to get the ecosystem up to speed as quickly as possible. Long term, we’re going to solve this problem entirely. Here’s how:&lt;/p&gt;

&lt;p&gt;Grunt v0.5 will ship with support for a new plugin format called &lt;a href="http://github.com/tkellen/node-task"&gt;node-task&lt;/a&gt;. It defines a stateless, promise-based, event emitting API that doesn’t depend on Grunt. It has a real-live spec, and the Grunt team is working with the front-end developer community in the hopes that compliant modules will be compatible with every task runner under the sun. When it’s done, it will ship with a test suite that anyone can use to build their own tasks.&lt;/p&gt;

&lt;h3 id="further-reading"&gt;Further reading&lt;/h3&gt;
&lt;p&gt;Phew, you made it to the end—thanks for hanging with me. If you’d like to know more about Grunt, please read our &lt;a href="http://gruntjs.com/getting-started"&gt;Getting Started Guide&lt;/a&gt;, and check out all of the ways you can &lt;a href="http://gruntjs.com/configuring-tasks"&gt;configure your tasks&lt;/a&gt;, too.&lt;/p&gt;

&lt;p&gt;Grunt on!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/QbIIwUsrse0" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 18 Feb 2013 15:26:14 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/tearing-grunt-apart</feedburner:origLink></item>
      <item>
        <title>Hangout with Bocoup</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/hangout-with-bocoup</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/st1KgN05kHY/hangout-with-bocoup</link>
        <author>Jory Burson</author>
        <description>&lt;p&gt;The Bocoup Loft is a fun and inspiring place to be. Between the technical debates and conversations amongst Bocoupers, regularly scheduled &lt;a href="http://training.bocoup.com"&gt;classes&lt;/a&gt; and &lt;a href="http://loft.bocoup.com"&gt;meetups&lt;/a&gt;, and the occasional &lt;a href="http://www.facebook.com/media/set/?set=a.393600370695734.104553.259954310727008&amp;amp;type=3"&gt;banana-themed event&lt;/a&gt;, 355 Congress St. is a very lively place!&lt;/p&gt;

&lt;p&gt;For the past few months, we’ve been experimenting with bringing that liveliness online via our &lt;a href="https://plus.google.com/101066175187812737186/posts"&gt;Bocoup on Air series with Google+&lt;/a&gt;. We’re inviting you, the open web developers of the world, to share ideas, questions, and discussions with one another in order to (hopefully!) learn something new and get to know more people in the community. So far, we’ve talked about &lt;a href="http://www.youtube.com/watch?v=9MZoB9_-SDE&amp;amp;feature=plcp"&gt;JavaScript and robots&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=y4rib9zKY9Y"&gt;HTML5 game development&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=vIKedYMm3D4"&gt;mobile development on the open web&lt;/a&gt;, and &lt;a href="http://www.youtube.com/watch?v=wXQoJm_8ukY"&gt;contributing to Open Source&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblog.bocoup.com/author/ben-alman/"&gt;Ben Alman&lt;/a&gt;, &lt;a href="http://weblog.bocoup.com/author/boaz-sender/"&gt;Boaz Sender&lt;/a&gt;, and others will be talking about JavaScript build tools and workflows at our next hangout this Thursday, Feb. 21 at 2:30 EST. &lt;a href="https://plus.google.com/u/0/b/101066175187812737186/events/cfqhgap40k38i0oqk93egue4sgs"&gt;RSVP&lt;/a&gt; or post a question for the discussion on &lt;a href="https://plus.google.com/101066175187812737186/posts"&gt;Bocoup’s Google+ page&lt;/a&gt;, and join us in the &lt;a href="http://webchat.freenode.net/?randomnick=1&amp;amp;channels=bocoup&amp;amp;uio=d4"&gt;#bocoup channel&lt;/a&gt; on the freenode IRC network for real-time conversation. If you can’t make it at 2:30, you can follow &lt;a href="http://www.youtube.com/user/bocoupllc"&gt;our YouTube page&lt;/a&gt; to watch the recording later.&lt;/p&gt;

&lt;p&gt;We hope you’ll hangout with us at the Loft or online soon!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/st1KgN05kHY" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 18 Feb 2013 01:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/hangout-with-bocoup</feedburner:origLink></item>
      <item>
        <title>Bring Out Your Bugs!</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/bring-out-your-bugs</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/CALKWd0w1-s/bring-out-your-bugs</link>
        <author>Irene Ros</author>
        <description>&lt;p&gt;At Bocoup, we’ve long been advocates of bringing open source practices to new communities wherever we go. That’s why we’re excited to join &lt;a href="http://openhatch.org/"&gt;OpenHatch&lt;/a&gt; and &lt;a href="http://www.hcs.harvard.edu/~harvardwomenincs/"&gt;Harvard Women in CS&lt;/a&gt; at Harvard University this weekend to introduce the &lt;a href="http://harvard.openhatch.org/"&gt;student community&lt;/a&gt; to the open source process. OpenHatch is a non-profit dedicated to matching prospective free software contributors with communities, tools, and education. &lt;/p&gt;

&lt;p&gt;We began &lt;a href="http://weblog.bocoup.com/popcorn-js/"&gt;our work with students&lt;/a&gt; at &lt;a href="http://cdot.senecac.on.ca"&gt;Seneca College’s Center for the Development of Open Technology&lt;/a&gt;while on &lt;a href="http://popcornjs.org/"&gt;Popcorn.js&lt;/a&gt;, and are excited to bring that experience to OpenHatch this Saturday, Feb. 16. While students commonly use Open Source projects in their coursework, the concept of ‘open source’ is rarely a topic of discussion in the classroom. Nonetheless, we at Bocoup believe that using and contributing to open source come hand-in-hand. And helping out is easier than you think! Conveniently, the easiest way to get started is through working on bugs and other project needs, which is where you come in.&lt;/p&gt;

&lt;h2 id="how-can-you-help"&gt;How can you help?!&lt;/h2&gt;

&lt;p&gt;We’re reaching out to you, the community of open source developers, to submit links to bugs or projects on github that need help. We can’t guarantee that we’ll address all your issues, but we’ll do our best to identify issues the students can tackle, and hopefully submit a few pull requests in the process. &lt;/p&gt;

&lt;p&gt;Please submit your bugs and other requests &lt;a href="https://docs.google.com/a/bocoup.com/forms/d/1mhe0mAdofdrGBhMKrUL9LJJ_TGIaUIgvF9sB4fr2yrA/viewform"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;iframe src="https://docs.google.com/a/bocoup.com/forms/d/1mhe0mAdofdrGBhMKrUL9LJJ_TGIaUIgvF9sB4fr2yrA/viewform?embedded=true" width="550" height="700" frameborder="0" marginheight="0" marginwidth="0"&gt;Loading...&lt;/iframe&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/CALKWd0w1-s" height="1" width="1"/&gt;</description>
        <pubDate>Wed, 13 Feb 2013 15:26:14 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/bring-out-your-bugs</feedburner:origLink></item>
      <item>
        <title>Welcome Adam Hyland</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/welcome-adam-hyland</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/xDURWcD4k0c/welcome-adam-hyland</link>
        <author>Cassie Irwin</author>
        <description>&lt;p&gt;We are pleased to announce that Adam Hyland has joined the Bocoup team as a data visualization intern.&lt;/p&gt;

&lt;p&gt;Adam brings expertise in statistical software development and data modeling to Bocoup’s data visualization projects. Through his background as an economist and R programmer, Adam has a wealth of experience in data handling and visualization, as well as building and assessing statistical models.&lt;/p&gt;

&lt;p&gt;We are excited to have Adam on the team, and looking forward to working with him to grow as an Open Web developer! &lt;/p&gt;

&lt;p&gt;You can follow &lt;a href="http://twitter.com/therealprotonk"&gt;Adam on Twitter&lt;/a&gt; and &lt;a href="https://github.com/protonk"&gt;GitHub&lt;/a&gt;, or pop by Bocoup to talk with him more about his work on Wikipedia.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/xDURWcD4k0c" height="1" width="1"/&gt;</description>
        <pubDate>Mon, 11 Feb 2013 01:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/welcome-adam-hyland</feedburner:origLink></item>
      <item>
        <title>Sessions: The vim Feature You Probably Aren't Using</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/sessions-the-vim-feature-you-probably-arent-using</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/LV_MNtfOPoI/sessions-the-vim-feature-you-probably-arent-using</link>
        <author>Adam J. Sontag</author>
        <description>&lt;p&gt;I may as well come out and say it. In 2010, I leapt directly from Dreamweaver to &lt;a href="http://www.vim.org/"&gt;vim&lt;/a&gt; as my primary editor. (I’ve been told that I may be the only person ever to have made this jump, but have no concrete evidence to substantiate this claim.) I had grown tired of Dreamweaver’s engorged appetite for RAM, and had grappled with vim enough in the context of my dealings with my VPS and git that I had already needed to at least &lt;em&gt;kinda&lt;/em&gt; learn how it worked. One of the major things that pushed me over the edge was catching a glimpse – I’m not sure where, maybe in &lt;a href="https://code.google.com/p/macvim/"&gt;MacVim’s&lt;/a&gt; menu – of the word “session.”&lt;/p&gt;

&lt;p&gt;Part of the reason Dreamweaver was so gluttonous was because I kept every file from every project that I was working on at a time open at once. I had begun to dabble with TextMate and e, and found it incredibly convenient (read: sane) to be able to keep separate projects grouped together. Surrounded as I was, however, by a bunch of vocal vim partisans, its allure was irresistible, espcially once I realised it could provide me this very same convenience.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://bocoup.com/img/weblog/house-cat.gif" style="float: right; margin: 0 0 20px 20px;" /&gt;&lt;/p&gt;

&lt;p&gt;After a couple of hours (or even days) of working on a project in vim, it starts to have its own character. You get a bunch of tabs open, and then each one ends up with its own set of &lt;a href="http://blogs.sourceallies.com/2009/11/vim-splits-an-introduction/"&gt;splits&lt;/a&gt;, and sure enough you know to go over &lt;em&gt;here&lt;/em&gt; when you need to take a look at the config, and to go over &lt;em&gt;there&lt;/em&gt; when you need to iterate on the new component you’ve been working on that week. You’ve built yourself a place to live, but you’re just renting. vim’s &lt;a href="http://vimdoc.sourceforge.net/htmldoc/usr_21.html#21.4"&gt;&lt;strong&gt;session&lt;/strong&gt;&lt;/a&gt; features will let you make that house a home.&lt;/p&gt;

&lt;p&gt;When you’ve been working for awhile and you’re all moved in to your new digs – maybe it’s the end of the day, maybe it’s been 71 days and you finally have to give in and restart your computer, you just save the session file to anywhere you’d like (I like &lt;code&gt;~/.vim/sessions/&lt;/code&gt;) using &lt;code&gt;:mksession&lt;/code&gt; (or &lt;code&gt;:mks&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:mks ~/.vim/sessions/rooster.vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next time you’re ready to start working on that project, source that session file within vim:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:source ~/.vim/sessions/rooster.vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or open it when you run vim using the &lt;code&gt;-S&lt;/code&gt; flag: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;vim -S ~/.vim/sessions/rooster.vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Boom. Everything will be exactly as you left it: the working directory, your windows, splits, and &lt;a href="http://vim.wikia.com/wiki/Vim_buffer_FAQ"&gt;buffers&lt;/a&gt;, and any options you’ve &lt;code&gt;:set&lt;/code&gt;. When the cycle repeats as you rearrange the furniture, just overwite the old session by using &lt;code&gt;:mks!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sessions don’t save &lt;a href="http://vim.wikia.com/wiki/Using_marks"&gt;marks&lt;/a&gt;, &lt;a href="http://usevim.com/2012/04/13/registers/"&gt;registers&lt;/a&gt;, or command line history (which are stored in &lt;a href="http://vimdoc.sourceforge.net/htmldoc/starting.html#viminfo-file"&gt;viminfo&lt;/a&gt;), but this hasn’t been a hindrance so far, and should you want to persist it, you can. If you want to further bake the use of sessions into your vim experience, Peter Odding’s &lt;a href="http://peterodding.com/code/vim/session/"&gt;session.vim&lt;/a&gt; plugin adds a number of helpers for working with session files, and integrates session saving into the default vim workflow. I’ve only just discovered it in the process of researching this post, but I’m certainly looking forward to giving it a shot; it’s an epic pain when you forget to save a long-running session and you’re left traveling back in time the next time you resume your project.&lt;/p&gt;

&lt;p&gt;Having my editor become a comfortable and familiar space, on a project-by-project basis, has been a huge boon. It’s immensely useful when you’re neck-deep in a project, and it’s a downright pleasure when stepping back into something you worked on a year earlier feels like returning to an old friend’s pad.&lt;/p&gt;

&lt;p&gt;While this may be old hat to some, I’m sure it’s news to others. I’m not exactly the Gandalf of vim, but I couldn’t help the feeling that a lot of people are missing out on the magic here. What do you think? Excited to go cozy up in the comfort of your new digs? Dying to point out some subtlety that I’ve missed? Let’s continue the discussion in the comments!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/LV_MNtfOPoI" height="1" width="1"/&gt;</description>
        <pubDate>Fri, 8 Feb 2013 12:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/sessions-the-vim-feature-you-probably-arent-using</feedburner:origLink></item>
      <item>
        <title>A Bientot, Rebecca</title>
        <guid isPermaLink="false">http://weblog.bocoup.com/a-bientot-rebecca</guid>
        <link>http://feedproxy.google.com/~r/bocoup/~3/dfSFDeo1tSY/a-bientot-rebecca</link>
        <author>Boaz Sender</author>
        <description>&lt;p&gt;Today, we’re saying goodbye to Rebecca Murphey. While we will miss her regular presence at Bocoup, we’re excited to continue working together on community projects as we have in the past. &lt;/p&gt;

&lt;p&gt;I met Rebecca four years ago when we were both green jQuery developers. I have learned so much from her over the years, and so it has been a special honor for me to work with her this past year. Rebecca has an incredible intuition for community-driven software design, as well as understanding and articulating the nuances of tomorrow’s problems. Rebecca’s influence on the community is huge, and I feel lucky that she touched Bocoup.&lt;/p&gt;

&lt;p&gt;We are so thrilled with the work she did while part of our team. Over the past year, Rebecca introduced two new classes to &lt;a href="http://training.bocoup.com"&gt;Bocoup Training&lt;/a&gt;, built and released the new interactive &lt;a href="http://jqfundamentals.com"&gt;jQuery Fundamentals&lt;/a&gt;, developed our &lt;a href="http://training.bocoup.com/coaching"&gt;coaching product&lt;/a&gt;, started our &lt;a href="http://training.bocoup.com/screencasts"&gt;screencasts program&lt;/a&gt;, and kicked off &lt;a href="https://plus.google.com/101066175187812737186/posts"&gt;Bocoup on Air&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rebecca is leaving Bocoup better than she found it. We are all eager to see the ways in which she continues to be a steward of the Open Web, and we’re looking forward to collaborating with Rebecca outside of Bocoup.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bocoup/~4/dfSFDeo1tSY" height="1" width="1"/&gt;</description>
        <pubDate>Fri, 18 Jan 2013 01:00:00 +0000</pubDate>
        <feedburner:origLink>http://weblog.bocoup.com/a-bientot-rebecca</feedburner:origLink></item>
  </channel>
</rss>
