<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bryan Summersett</title>
 <link href="http://bsumm.net/atom.xml" rel="self"/>
 <link href="http://bsumm.net/"/>
 <updated>2013-09-29T20:19:51-07:00</updated>
 <id>http://bsumm.net/</id>
 <author>
   <name>Bryan Summersett</name>
   <email>bsummersett@gmail.com</email>
 </author>

 
 <entry>
   <title>The Latency of Dialogue</title>
   <link href="http://bsumm.net/2013/09/29/the-latency-of-dialogue.html"/>
   <updated>2013-09-29T00:00:00-07:00</updated>
   <id>http://bsumm.net/2013/09/29/the-latency-of-dialogue</id>
   <content type="html">&lt;p&gt;Check out my latest post, &amp;quot;&lt;a href=&quot;https://medium.com/how-to-use-the-internet/3fb3669cc794&quot;&gt;The Latency of Dialogue&lt;/a&gt;,&amp;quot; on Medium. It&amp;#39;s about our collective fascination with Internet streams, and what we&amp;#39;re missing out on because of it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A transcription of High Density</title>
   <link href="http://bsumm.net/2013/08/02/a-transcription-of-horace-dedius-high-density-podcast.html"/>
   <updated>2013-08-02T00:00:00-07:00</updated>
   <id>http://bsumm.net/2013/08/02/a-transcription-of-horace-dedius-high-density-podcast</id>
   <content type="html">&lt;p&gt;The following is a loose transcription of Horace Dediu&amp;#39;s &lt;a href=&quot;http://www.asymco.com/2013/07/22/high-density-2-tim-bajarin/&quot;&gt;&lt;em&gt;High Density&lt;/em&gt; podcast&lt;/a&gt;, a spinoff of his excellent &lt;em&gt;Critical Path&lt;/em&gt; series. The conversation is between Horace and Tim Bajarin, a technology analyst of many years. Tim offers a compelling summary of the history of the PC industry, one which I find increasingly relevant, as Horace points out, for its parallels to the mobile OS landscape, especially the parallel between IBM and Google&amp;#39;s strategy for PCs and Android, respectively. Also crucial is the observation of a continual pattern in platform lifecycles: &amp;quot;hardware, software OS, SDK, innovative apps, and ... explosion.&amp;quot; It was also news to me that Alan Kay ultimately had a lot of influence on John Sculley&amp;#39;s vision for computing, as Alan was a fellow at Apple during Sculley&amp;#39;s tenure. &lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;h2&gt;Transcript&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Horace:&lt;/strong&gt; I&amp;#39;m joined today by Tim Bajarin. Tim is someone that people in the technology industry have been following for a long time. He&amp;#39;s the head of Creative Strategies, although you do more than that. Can you give people some more background to your story?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tim:&lt;/strong&gt; I joined Creative Strategies as a PC analyst. When we started, there were no PC analysts. There were four people in a role similar to mine, and we picked up the PC as part of other work. I was able to literally watch it from day one: Don Estridge from IBM and his team, as well as Apple. I&amp;#39;ve been following them (Apple) since 1971, and have interacted with all of its top leaders over the last 35 years. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; You&amp;#39;re a fountain of knowledge in this industry. I&amp;#39;ve been an analyst for a short time, but an engineer for a long time. I myself cut my teeth doing software development on the PC. Maybe you can share some stories about how these organizations evolve.&lt;/p&gt;

&lt;p&gt;In particular, I&amp;#39;m curious about how technology organizations actually emerge. When  I crossed over from technology to business, in a career sense, technology businesses were seen as another kind of normal business. I always thought that it requires a different kind of operating model, one that wasn&amp;#39;t dealing with commodities (well, eventually they do), but in the beginning no one knows how to create products, and things are extremely volatile. &lt;/p&gt;

&lt;p&gt;How do you think about the history of Apple, etc. Did they know what they were doing? How did they come about creating these mechanisms of production? MS started a certain culture, etc. How did it happen?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tim:&lt;/strong&gt; PC industry was a happy accident. Eddie Roberts introduced the first PC in 1974, and it was on the cover of Popular Mechanics. Following this, Bill Gates wrote most of the OS and flew out to Albuquerque.&lt;/p&gt;

&lt;p&gt;Steve Jobs and Wozniak saw this happening, and they wanted to buy this PC kit, but Woz didn&amp;#39;t have the money. So he figured out how to do it for himself. It started with the garage mentality that Silicon Valley is now famous for.&lt;/p&gt;

&lt;p&gt;Jobs had the mentality: if we both wanted it, other people might want it too. So they go and order 400 kits right off the bat, which later become the Apple I, and they went bananas thinking it might be big. Jobs sold his Volkswagen to finance the purchases. &lt;/p&gt;

&lt;p&gt;I&amp;#39;ve dealt with hundreds of entrepreneurs. It always starts with a mindset of people wanting something for themselves, and only later it happens to turn into something akin to  market research. &lt;/p&gt;

&lt;p&gt;Seasoned businessman took the gamble on financing them later (Mike Markkula). They had to hire engineers, Steve had to handle marketing, but even until &amp;#39;82, &amp;#39;83, it was still led by young people, and these people were not seasoned in business. That was one of the reasons they eventually tapped John Sculley, being a serious leader. &lt;/p&gt;

&lt;p&gt;IBM&amp;#39;s foray into the PC market was spearheaded by Don Estridge. He went to top management, wrote a business plan, and convinced them of a business plan to back the PC. In the end, the whole endeavor would&amp;#39;ve failed if it weren&amp;#39;t for VisiCalc. &lt;/p&gt;

&lt;p&gt;The original Apple II was a hobbyist machine. People used it for bulletin boards, etc., but there were really no significant apps. With the addition of the CP/M board, however, there was more interest. The thing that would change the potential of the PC in the minds of the lay public was VisiCalc. Dan Bricklin and Bob Frankston. I remember using it, and my mind was boggled. Now I can do rows and columns and sum them up. The computer could do it for you! It changed everything. This was first most useful for small businesses, but even corporate accounts were becoming fascinated with its role as a spreadsheet.&lt;/p&gt;

&lt;p&gt;Estridge was thinking there was something to this PC.&lt;/p&gt;

&lt;p&gt;The real catalyst for VisiCalc, in the end, was the possibility of developing 3rd party applications. The developer kit was what that allowed people to develop their own applications, and this was the same thing with DOS. IBM&amp;#39;s PC didn&amp;#39;t take off until there was an SDK to create apps. That pattern goes across everything that&amp;#39;s done today -- it&amp;#39;s a continual pattern: hardware, software OS, SDK, innovative apps, and explosion. &lt;/p&gt;

&lt;p&gt;From an IBM standpoint, they were lucky. It was a gamble. Difference was that IBM went at it with a lot of capital. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; The notion of taking a huge gamble, without knowing necessarily where the product will find a job for itself... It wasn&amp;#39;t until the iPhone&amp;#39;s apps that the platform took off, and the use cases came with the apps. We&amp;#39;re still at an early phase with the iPad (not clear whether it has a natural set of functions about it). &lt;/p&gt;

&lt;p&gt;Stepping back, it sounds like these organizations were chaotic; lots of activity to execute on basics. Having adult supervision, or the lack of. When Apple did try to structure themselves into a traditional, rigorous way, they lost that edge. Is there a correlation? IBM could execute better on some dimensions, but they were essentially following in the footsteps of Apple.&lt;/p&gt;

&lt;p&gt;Does this mean that when you&amp;#39;re trying to optimize, develop a market, maybe the best approach is not to be structured?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Yes and no. Sculley did create more structure, and yet Apple continued to grow until 1992. Steve left after 1984. Sculley managed it relatively well, but he took it into a niche area instead of its full potential market. It was already focused on engineering / technical markets, but the introduction of PageMaker, combined with the laser printer,  spawned desktop publishing, which also spawned a change as great as VisiCalc. This was also the first foothold in Hollywood from this change.&lt;/p&gt;

&lt;p&gt;IBM&amp;#39;s design decision was very different: Apple had the vertical integration. In IBM&amp;#39;s case, they used off-the-shelf parts. They were forced to create an SDK. Even though they had structure, they didn&amp;#39;t have protection from a competitive position. &lt;/p&gt;

&lt;p&gt;I&amp;#39;ve spoken with Rod Canion, who founded Compaq. I asked him, &amp;quot;what made you think about creating a PC clone?&amp;quot; Rod had been at TI, and said he learned one thing: whenever IBM did something, it became a standard, so it was a no-brainer. &lt;/p&gt;

&lt;p&gt;Sculley introduced the concept of the CD-ROM to computers, and thought that was the future of computing. &lt;span class=ref&gt;&lt;a href=&quot;http://kensegall.com/2012/07/maybe-sculley-wasnt-so-after-all/#comment-597662718&quot;&gt;HyperCard too&lt;/a&gt;, it seems.&lt;/span&gt; He brought Negroponte, the CEO of Bell Labs, and a bunch of other people together based on the idea of the CD-ROM, which they all believed could create a new age of communication. Even though IBM left them less controlled, Apple had structure, but kept them in a niche market, Apple didn&amp;#39;t get the growth because of the path they took, even though they were structured. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; They weren&amp;#39;t able to pivot to a structured mode that was successful, because they needed to maintain control over the pieces, so they couldn&amp;#39;t optimize to the licensing model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Once IBM realized they had nothing proprietary, they tried to make one called PS/2. Rod Canion stood up to IBM, at that time a gnashing decision, and from the industry standpoint, their decision to not back this was the primary reason we have a free, open, PC clone architecture today. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; So they didn&amp;#39;t necessarily want an open architecture in the end. They never had ownership of that market. It&amp;#39;s interesting to think about how Android works in a similar way -- whether they have control over the destiny of that franchise.&lt;/p&gt;

&lt;p&gt;What about the period of time between &amp;#39;92, when Apple was growing, until when Jobs came back? What happened in the meantime? Was there changing organizational behavior inside Apple: discussions about going back to its creative roots, etc. What did the organization look like between &amp;#39;92 and &amp;#39;97? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; What was significant was after taking Sculley out, Apple was handed to Michael Spindler. It was curious in that they were largely where Apple is today &lt;span class=ref&gt;Presumably he means that they they&amp;#39;re leading in their industry&lt;/span&gt;. Apple did well in the niche market, and two years after having the lead in desktop publishing, the PC got caught up. Within two years of owning the multimedia technologies space, others were already catching up. Apple needed to go beyond a niche company, be better. They were concerned that they were losing so much ground over the PC, they began thinking that they needed to make it look like a PC. There was confusion over licensing and non-licensing; they did a deal with Motorola. In 3 years of Spindler, Apple was in serious decline, and then eventually brought in Gil Amelio. Mike&amp;#39;s a great guy, but wasn&amp;#39;t the right person for that period.&lt;/p&gt;

&lt;p&gt;Then handed it to Gil, even though he was a board member at Fairchild at the same time. Realized that they had to control things better, and his position was that they couldn&amp;#39;t be all things to all people. By that time, they had lost control, and they weren&amp;#39;t growing their OS at the core. The OS didn&amp;#39;t have a growth pattern, and had the foresight to see that NeXT (UNIX) had the potential of leveraging that OS to move forward. Apple had gone down, was over 1 billion in the red, and we now know they were 6-7 weeks from bankruptcy. &lt;/p&gt;

&lt;p&gt;This gets interesting, because when Jobs got back in &amp;#39;97, I asked how he would rescue Apple. He said, &amp;quot;In the last 5 years, we&amp;#39;ve taken the eyes off the ball. Fundamentally, I&amp;#39;m going to do the best I can for graphics people, engineers.&amp;quot; He wanted to go back to the graphics arts, publishing, TV, etc.: the original core customers of Apple&amp;#39;s business. The other thing he said is that I&amp;#39;m going to concentrate on industrial design, which I found totally confusing at the time. &lt;/p&gt;

&lt;p&gt;And yet a year later came the iMac. 3 years later is the iPod. Eventually he brings out the iPhone. Steve brought back a vision, and luckily, through its board, they brought more structure to that vision, and with that level of structure and vision, Apple is where it is today. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; People think that they primarily wanted Steve back, but it was more pragmatic than that: there was something very useful and timely about the NeXT offering at the time, not just the OS, but it had a great development environment. It had the Objective-C environment, the OO-orientation of the platform... Novel at the time, and powerful and seen as guiding the future. The NeXT acquisition was driven by the need to reboot and reconfigure the OS 9 franchise, and Steve Jobs provided that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Once they started talking about that, Gil knew they were missing a vision. I dealt with all the leaders besides Steve, and Sculley was the only one who had a good vision. Sculley was highly influenced by Alan Kay, and Alan was extremely influential on his thinking on education, mobile computing, etc. Having said that, at the particular time, John was becoming much more visionary in the context of graphics arts (he was a former architect). John knew everything was going to go digital, and was fascinated with his vision. He said someday we were going to have billions of devices some day... He was the first CEO I dealt with who literally said we&amp;#39;re moving from an analog to a digital world, and nothing can stop that. He was becoming more visionary in that role, and the part of the business that needed to grow was they were stuck in these niches while the PC market was exploding. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; Jobs had more vision, but was extremely pragmatic in how he would get out of that hole.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; He also mellowed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; He also learned a lot with Pixar, and I&amp;#39;m fascinated with how much the Pixar experience influenced his management expertise: how you manage creative people, how you deal with the entertainment industry, etc. Do you find this to be true?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Pixar had a huge influence on him, but you have to believe his take on media in general had to change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; There&amp;#39;s the thought that companies are surfing this wave of technology, and you can&amp;#39;t optimize and control a product category. This is a crucial dilemma for a technology company: whether you grab an opportunity and optimize it, or you say perhaps optimization and creativity are orthogonal, and either you create a hybrid sustaining / disruptive, or you choose to be constantly sustaining. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; There&amp;#39;s a couple things going on. Steve understood content was important, and controlling it was also important. Years before, when Akio Morita (Sony) bought a movie studio (Universal), I happened to be at an event with key analysts, and we asked him: why would Sony buy a movie studio? He said, &amp;quot;It&amp;#39;s just software.&amp;quot; Even then, he understood that what we had in the movies would eventually become digitized like software. Jobs at Pixar understood this as well. The message was clear. Content is king, and it was clear to him then. I believe Jobs was strategically thinking this through from &amp;#39;98 to &amp;#39;00, and eventually he realized he had to build hardware, software, and services together. With the iPod, he had this in mind, because he had to find a way to distinguish himself from the market. The Mac was still within the context of a commoditized market, but in the end, you had to have a certain level of vertical integration to control your destiny. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; It&amp;#39;s hard to define success and failure. It&amp;#39;s always nuance and subtlety. We&amp;#39;re trying now to think of what went on in his mind. As he mellowed and aged, and saw what he built become corrupted, I wonder how much he thought about how to build an organization that will last in the midst of market forces: sometimes you get lucky, sometimes not, and how do you keep the creative spirit going. It comes back to anecdotes about why people work at Apple. Why do people stay in the organization even when failing? Some of it might be due to a fear of the unknown, but I wonder how the cultural aspects of Apple were shaped by Jobs before and afterwards. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; You can see this in some of the predominant cultural aspects of Silicon Valley today: they all believe what they&amp;#39;re doing will change the world. The Yahoos, etc., all believed they were going to transform the way people enjoy something. There&amp;#39;s a tendency for it to be a cliché today, but you go to Apple, and they&amp;#39;ll tell you they&amp;#39;re there because they have a vision. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; That&amp;#39;s a common theme of startups. What was unique about Apple in particular? Is it a track record, leadership, or was there an operating model where this was the place where stuff gets done? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; You could look at Apple&amp;#39;s historical position: they didn&amp;#39;t invent the PC, they reinvented it. They didn&amp;#39;t invent publishing, but they reinvented it. They didn&amp;#39;t invent the phone, they reinvented it. The driving force is that we can reinvent the watch, the car... there&amp;#39;s enough understanding of Apple&amp;#39;s track record (which is highly unique -- reinvent technology sectors over and over, and the people there still think there&amp;#39;s things to invent and disrupt.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; This exceptionalism about Apple divides people. Speaking of the future, how do you see Apple&amp;#39;s current structure / team / culture as it exists today? Is it built to last? Second question: what do you think they&amp;#39;re going to go with this structure in the future? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; The current VPs were all schooled in the Jobsian vision. We have examples of this too. After Walt Disney died, people thought the company was going to lose its momentum. Look at Disney now! Of all the companies I track, I still think that Apple has the best chance to do this over the others. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; What&amp;#39;s your take on what they might do with their organizational and cultural makeup; their resources and processes, and priorities? Do you think there&amp;#39;s a roadmap out there (watches, television)... How do you see that thinking going? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; One thing that&amp;#39;s intriguing about Apple has always been the fact that they were always forward thinking on user interfaces. The mouse was brought to us by them (popularized); touch UIs; voice UIs. Other areas they continue to disrupt are in user interfaces -- gestures, head tracking. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; That&amp;#39;s an observation I&amp;#39;ve made as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; They disrupt user interfaces by the nature of the product they deliver. We didn&amp;#39;t need touch on a desktop, but we sure did on a smartphone. On a TV, we don&amp;#39;t need touch, but we need to reinvent the user interface to make it smarter. I absolutely believe they&amp;#39;re going to make a watch. Years before, I highlighted explicitly the watch and car industry as industries they could reinvent. No question they&amp;#39;re going to get it right. I have a digital watch, which Seiko introduced in 1981. Automobiles: I want it to be much smarter than it is today. iOS 7 with its car integration is going to be even more important going forward. If we think Apple&amp;#39;s done innovating and disrupting, we need to stop and check ourselves. &lt;/p&gt;

&lt;p&gt;There was an article about major leaders saying Apple is dead -- Michael Dell, etc. How many times has someone said Apple will &lt;em&gt;not&lt;/em&gt; die? If the company has a vision, and the employees believe in it, with a track record like they do, there&amp;#39;s something there. If I was going to bet on a big company disrupting markets, it would be Apple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; That&amp;#39;s a real endorsement. I wanted to make sure that folks can follow you...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;T:&lt;/strong&gt; Twitter is &lt;a href=&quot;https://twitter.com/Bajarin&quot;&gt;@bajarin&lt;/a&gt;. I do  &lt;a href=&quot;http://techpinions.com/&quot;&gt;Techpinions&lt;/a&gt; with my son and three others. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;H:&lt;/strong&gt; For someone in it since the beginning, I&amp;#39;m heartened to hear affirmation that the pioneer is still there. It&amp;#39;s a testament to the power of their vision. What made Apple sustain itself, despite being disrupted, was moving forward and having the organization and resources to build the next thing, and the vision is the crucial element. It&amp;#39;s causal in the sense that if it didn&amp;#39;t exist, the vision would fail. Does this apply to other companies as well? &lt;/p&gt;

&lt;p&gt;The presence of vision is crucial, and if you&amp;#39;re in the technology business, it&amp;#39;s primarily important. &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>You have a design problem</title>
   <link href="http://bsumm.net/2013/05/28/you-have-a-design-problem.html"/>
   <updated>2013-05-28T00:00:00-07:00</updated>
   <id>http://bsumm.net/2013/05/28/you-have-a-design-problem</id>
   <content type="html">&lt;p&gt;&lt;em&gt;The following is an interpretive transcription of &lt;a href=&quot;https://peepcode.com/products/design-bundle&quot;&gt;Ryan Singer&amp;#39;s UX / UI PeepCode sessions&lt;/a&gt; in the style of Paul Arden&amp;#39;s &lt;a href=&quot;http://www.amazon.com/Its-Not-How-Good-Want/dp/0714843377&quot;&gt;It&amp;#39;s Not How Good You Are, Its How Good You Want to Be&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;

You have a design problem.


Ask:
How did they get there?

What&#39;s going to happen when they&#39;re done?


Before, now, after.



Constrain the domain so the problem is simpler.
Think of the real-world analogy.


Draw information flows:
relations based on navigation trees.


Think about state.
Does it matter?

Is this a micro-domain? It can be transient.
Is this is social thing? The scale is bigger.

Email is UI too.

Split the UX into beginning, middle, and end contexts.
Afterwards, design for the screen with these in mind.



What screen matters most?

Find the simplest screen that:
forces you to be compelling
provides value
and contains no unnecessary detail.

This teaches you about the product.

Doing the most complicated thing first may be tempting,
but this may never be used.

Think of UX like a failing test.
There&#39;s always conflict.
Identify the thing that I don&#39;t know, and build it out. 
Remove uncertainty.


Consider the naive approach first.

Find the natural way of doing things.
If I did this in the physical world, 
what would its most natural-looking interface be?

(Scribbles on paper?)


Try to communicate using their vocabulary.

What&#39;s the dumbest idea that works?
If this were paper, how would I do it? 



Christopher Alexander said
conflict is the starting point.

What conflicts exist?
*Weirdness* is conflict.
Increase confidence by resolving conflicts through design.



Sometimes, it needs to be seen on screen to make a decision.

Confidence is a spectrum.

It&#39;s important to find group confidence in a design on a team.
Do this by working side by side on something.




Make the intended action clear.
One way to do this is guarantee there&#39;s only one thing to do.

Flows help.
Before, now, after.

Every step needs a concept and implementation.
They must be evident to the user.





Mock (in Photoshop) to explore alternatives.


Criteria for it working:
*reptile stuff*.

When I look at it...
how does it affect me?



Sketching UX doesn&#39;t mean doing everything. 
*Use as medicine to ease the pain of worrying.*

Prove clear thinking by sketching. Remove worry.
Just enough to know what you&#39;re doing.


Design on the wall is exactly this.
Temporary.
The point is: the designer, programmer work *together*
through the design.

Then they go work.



There&#39;s never a moment where everything is built.
Design only when I need to design.
See what&#39;s working from there.

Step by step.


&lt;/pre&gt;

&lt;p&gt;&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;

&lt;pre&gt;
To prototype your UI:

*Focus on one UI element at a time.*
Use whatever tool is most convenient. 

PS, Web Inspector.
Rails can be fast if you know it already.

Take screenshots.
Mash it up.
Throw it away.

Write it however you can to make it do what you want.
Don&#39;t plan your implementation.

You will externalize your CSS later anyway.
Write it inline. 

Write it the long, easy way.
Start with a mess.
Refactor when your conflicts are resolved.


Photoshop can remove doubt.
Use it to see something.
Mock it quick to see how it will look.
Throw it away.

&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Stay relevant</title>
   <link href="http://bsumm.net/2013/05/27/stay-relevant.html"/>
   <updated>2013-05-27T00:00:00-07:00</updated>
   <id>http://bsumm.net/2013/05/27/stay-relevant</id>
   <content type="html">&lt;p&gt;2005 M.I.A Pitchfork &lt;a href=&quot;http://web.archive.org/web/20050317044856/www.pitchforkmedia.com/interviews/m/mia-05/&quot;&gt;interview&lt;/a&gt;, describing the circumstances of her first album:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;M.I.A.: The thing that I got exposed to when I met Justine was a lot of middle-class kids making music in England who had everything at their disposal and nothing to say. They didn&amp;#39;t rep anything! Yet everybody was having soul-searching issues going, &amp;quot;Oh my Goooooood, who am I, what am I doing? I might have to go to a yoga retreat this year.&amp;quot; And I&amp;#39;d be like, &amp;quot;Why don&amp;#39;t you just look at what&amp;#39;s going on and be a part of the planet, instead of wanting to be what&amp;#39;s come before?&amp;quot; Which is how all those bands set themselves up-- they aspired to be [older] bands and forget what&amp;#39;s going on [today].&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Analyzing mbostock's <i>queue.js</i></title>
   <link href="http://bsumm.net/2013/03/31/analyzing-mbostocks-queue-js.html"/>
   <updated>2013-03-31T00:00:00-07:00</updated>
   <id>http://bsumm.net/2013/03/31/analyzing-mbostocks-queue-js</id>
   <content type="html">&lt;p&gt;Even with the proliferation of open source software on the web, relatively few developers take the time to study the source code of the software they might use everyday. I believe this can largely be traced back to a lack of culture around code reading, which I will hopefully talk about in a later post. To combat this for now, however, the answer is simple: we just need to practice looking at and studying the works of others, similar to the way painters &lt;a href=&quot;http://www.paulgraham.com/hp.html&quot;&gt;studied (and copied) the great masters&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Beginning today, I&amp;#39;m beginning a series of &amp;quot;deep dives.&amp;quot; First is a look into a tiny JavaScript asynchronous helper library called &lt;em&gt;queue&lt;/em&gt;, written by Mike Bostock (of &lt;a href=&quot;http://d3js.org/&quot;&gt;d3.js fame&lt;/a&gt;). Many libraries have been written prevent &amp;quot;callback spaghetti:&amp;quot; highly nested callbacks that need to be executed in some order. Many solutions have been implemented, from &lt;a href=&quot;http://promises-aplus.github.com/promises-spec/&quot;&gt;promises&lt;/a&gt; to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Iterators_and_Generators&quot;&gt;generators&lt;/a&gt; to a &lt;a href=&quot;http://taskjs.org/&quot;&gt;combination of both&lt;/a&gt;. Mike takes a simple approach: the API comprises one method, &lt;em&gt;defer&lt;/em&gt;, which takes in a task (a Node.JS-style function, whose last argument must be a completion callback), along with optional arguments. To get the results back, there&amp;#39;s &lt;em&gt;await&lt;/em&gt; and &lt;em&gt;awaitAll&lt;/em&gt;. These differ only in how they return their results array. Mike mentions the entire source can be compressed down to around 500 bytes, so this walkthrough shouldn&amp;#39;t take too long.&lt;/p&gt;

&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;First, though, I&amp;#39;d recommend looking at the &lt;a href=&quot;https://github.com/mbostock/queue&quot;&gt;repo on GitHub&lt;/a&gt;, or &lt;a href=&quot;https://raw.github.com/mbostock/queue/master/queue.js&quot;&gt;taking a quick peek at &lt;em&gt;queue.js&lt;/em&gt;&lt;/a&gt; directly before reading this to get a quick sense of the overall code structure. Here&amp;#39;s an example use of the API from the docs, reading two files in parallel and awaiting the combined results:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__dirname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/../Makefile&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;__dirname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/../package.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;file1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;&lt;em&gt;queue.js&lt;/em&gt;&lt;/h2&gt;

&lt;p&gt;Let&amp;#39;s begin. We start with an &lt;a href=&quot;http://stackoverflow.com/questions/5815757/what-exactly-is-the-point-of-this-function-construct-why-is-it-needed&quot;&gt;anonymous self-invoking function&lt;/a&gt;. &lt;span class=ref&gt;Note that &lt;a href=&quot;http://stackoverflow.com/questions/1634268/explain-javascripts-encapsulated-anonymous-function-syntax&quot;&gt;this parenthesis isn&amp;#39;t necessarily required&lt;/a&gt;; the JS parser just needs to treat this as a &lt;em&gt;function expression&lt;/em&gt; rather than a &lt;em&gt;function declaration&lt;/em&gt;, so a &lt;em&gt;+&lt;/em&gt; or &lt;em&gt;!&lt;/em&gt; would work as well.&lt;/span&gt;The surrounding parenthesis helps clarify to the reader that this function will be executed immediately.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we check for Node.js-style modules; if these exist, add &lt;em&gt;queue&lt;/em&gt; as a module. Otherwise add it to the &lt;em&gt;self&lt;/em&gt; object. &lt;span class=ref&gt;Assigning to &lt;em&gt;self&lt;/em&gt; was new to me, as I typically expect modules to assign to the &lt;em&gt;window&lt;/em&gt; global for browsers; however, it turns out most browsers resolve &lt;em&gt;self&lt;/em&gt; to &lt;em&gt;window&lt;/em&gt; in the global context, and to the Web Worker context &lt;a href=&quot;http://blog.vjeux.com/2011/javascript/javascript-one-line-global-export.html&quot;&gt;in a Web Worker&lt;/a&gt;. Thus, assigning to &lt;em&gt;self&lt;/em&gt; covers both contexts.&lt;/span&gt; Note it may also seem that &lt;em&gt;queue&lt;/em&gt; is undefined at this point; however, because JavaScript &lt;a href=&quot;http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting&quot;&gt;hoists variable names&lt;/a&gt; to the top of functions, the function &lt;em&gt;queue&lt;/em&gt; from below is actually available.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;undefined&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;1.0.3&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a shorthand for &lt;em&gt;Array.prototype.slice&lt;/em&gt;, and now we enter into our main function definition.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parallelism&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;queue&lt;/em&gt; is the object we return to the client at the end of this constructor. This initially seems confusing, as it shadows the name of the function immediately above, but this allows code below to read more naturally. Most other variables are already explained:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;started&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// number of tasks that have been started (and perhaps finished)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;active&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// number of tasks currently being executed (started but not finished)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// number of tasks not yet finished&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;popping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// inside a synchronous task callback?&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, &lt;em&gt;await&lt;/em&gt; and &lt;em&gt;all&lt;/em&gt; are interesting. In the context of the internals of &lt;em&gt;queue&lt;/em&gt;, the &lt;em&gt;await&lt;/em&gt; variable is a placeholder for the final callback function. &lt;em&gt;all&lt;/em&gt; here is a boolean that determines how the results should be handed back: either as separate arguments, or as an array. &lt;a href=&quot;https://github.com/mbostock/queue&quot;&gt;Read the documentation&lt;/a&gt; for more information.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Setting default parallelism is important for later on, as this variable is checked when popping tasks off our queue to ensure we&amp;#39;re not executing more than &lt;em&gt;parallelism&lt;/em&gt; tasks at a time.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parallelism&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parallelism&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;Infinity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we have &lt;em&gt;defer&lt;/em&gt;, our first public function. &lt;em&gt;defer&lt;/em&gt; slurps in its arguments and stores them to our current tasks. &lt;em&gt;defer&lt;/em&gt;&amp;#39;s API specifies its first argument is our task function, and the rest are optional arguments for that function.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we increment our count of remaining tasks, and then execute our &lt;em&gt;pop()&lt;/em&gt; method, where most of the the magic happens. We&amp;#39;ll look at this in a second. &lt;span class=ref&gt;Interesting detail: &lt;em&gt;defer&lt;/em&gt; tries to executes our tasks immediately, rather than waiting for &lt;em&gt;await&lt;/em&gt;, for instance. This means that we can call &lt;em&gt;defer&lt;/em&gt; after we &lt;em&gt;await&lt;/em&gt; and it should call &lt;em&gt;await&lt;/em&gt; again for us.&lt;/span&gt; So ends our &lt;em&gt;defer&lt;/em&gt; method.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;await&lt;/em&gt; method and &lt;em&gt;awaitAll&lt;/em&gt; methods are similar; they simply set the variables we were talking about, and optionally, if there weren&amp;#39;t any remaining tasks at this point, immediately notify our callback of our status. These methods also return their parent object, &lt;em&gt;queue&lt;/em&gt;, which enables a nice &lt;a href=&quot;http://en.wikipedia.org/wiki/Builder_pattern&quot;&gt;builder pattern-like&lt;/a&gt; API. See the &lt;a href=&quot;https://github.com/mbostock/queue&quot;&gt;examples in the documentation&lt;/a&gt; for how this is used.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;awaitAll&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Pop&lt;/em&gt; is the internal method responsible for popping remaining tasks off the queue and executing them, &lt;em&gt;n&lt;/em&gt; at a time, where &lt;em&gt;n&lt;/em&gt; is our &lt;em&gt;parallelism&lt;/em&gt; value. &lt;span class=ref&gt;The &lt;em&gt;popping&lt;/em&gt; variable here is used to signal to the task&amp;#39;s internal callback function whether or not we&amp;#39;re still actively popping tasks off our queue. This comes into play in the case when a task completes synchronously / immediately (i.e., not on the next event loop) so that we know not to fire the &lt;em&gt;pop&lt;/em&gt; call again.&lt;/span&gt; Now we get to the main &lt;em&gt;while&lt;/em&gt; loop for executing our tasks. We continue to spawn new tasks (via &lt;em&gt;started&lt;/em&gt;) until we run out of them, or we reach the max parallelism of tasks at the given time.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;popping&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;started&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;active&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;parallelism&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, within the loop, our index is the next started task. We find its arguments, &lt;em&gt;t&lt;/em&gt;, then extract its arguments from the input using &lt;em&gt;slice(..., 1)&lt;/em&gt;, which essentially removes the task function call from the arguments list. &lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;started&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, &lt;em&gt;callback&lt;/em&gt; returns the callback for a given task index, and pushes this as the new last argument; it&amp;#39;s a Node.JS convention to have the last argument as the callback. We then increase our active count and execute our task function with a null context and its arguments. Note that &lt;em&gt;this&lt;/em&gt; as context would be inappropriate here, as the called tasks shouldn&amp;#39;t have any knowledge of the &lt;em&gt;queue&lt;/em&gt; internals. So ends our while loop.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;active&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next is the &lt;em&gt;callback&lt;/em&gt; constructor implementation. Why do we need this function? Putting the callback directly in the while loop wouldn&amp;#39;t work, &lt;a href=&quot;http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example&quot;&gt;since JavaScript has &lt;em&gt;function scope&lt;/em&gt;&lt;/a&gt;, so our task index &lt;em&gt;i&lt;/em&gt; would contain the last written index value. Now we see that this constructor serves to close over the task index for the callback function. The returned callback takes in an optional error, and then a result value, which is a Node.JS convention.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we&amp;#39;re inside the internal callback function. Decrementing the active count means we can potentially start another task. If we have errors, set our error variable, which will implicitly dequeue all other tasks; we also notify our client immediately that an error has occurred. &lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;active&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ignore new tasks and squelch active callbacks&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;started&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;NaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// stop queued tasks from starting&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Otherwise, if our task executed successfully, store the result for this callback in the original task array. Check if there are any remaining tasks; if there are and we&amp;#39;re still popping tasks in our &lt;em&gt;while&lt;/em&gt; loop, do nothing, because the loop is dequeueing tasks already. Otherwise, start popping again. &lt;span class=ref&gt;Immediately returning / synchronous tasks don&amp;#39;t normally occur for tasks that involve I/O or ones that call &lt;em&gt;setTimeout&lt;/em&gt;, because these will typically trigger their callback on the next event loop tick.&lt;/span&gt; Finally, if there&amp;#39;s no remaining tasks, notify the client that we&amp;#39;re done.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;popping&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally &lt;em&gt;notify&lt;/em&gt;. This function executes the callback function given by the client in &lt;em&gt;await&lt;/em&gt; or &lt;em&gt;awaitAll&lt;/em&gt;. If there was a problem, report this as the first argument; otherwise call the callback either with a list of results or results as function arguments, depending on whether the API called was &lt;em&gt;awaitAll&lt;/em&gt; or &lt;em&gt;await&lt;/em&gt;, respectively.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;noop&lt;/em&gt; is used as a default value for the &lt;em&gt;await&lt;/em&gt; callback. This is an example of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Null_Object_pattern&quot;&gt;null object pattern&lt;/a&gt; and simplifies the implementation in &lt;em&gt;notify&lt;/em&gt;, so we don&amp;#39;t have to special case our logic if the &lt;em&gt;await&lt;/em&gt; callback was null.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;  &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;That wasn&amp;#39;t so bad, huh? It&amp;#39;s nice to see a library with that much utility in that little code. Hopefully there was at least something you learned from reading the source. If you&amp;#39;re interested in reading more async libraries for JavaScript, check out the source to &lt;a href=&quot;https://github.com/kriskowal/q&quot;&gt;kriskowal&amp;#39;s &lt;em&gt;q&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/tildeio/rsvp.js&quot;&gt;Tom and Yehuda&amp;#39;s &lt;em&gt;rsvp.js&lt;/em&gt;&lt;/a&gt;, or even &lt;a href=&quot;https://github.com/mozilla/task.js&quot;&gt;Mozilla&amp;#39;s experimental &lt;em&gt;task.js&lt;/em&gt;&lt;/a&gt; as well. &lt;/p&gt;

&lt;p&gt;Please &lt;a href=&quot;mailto:bsummersett@gmail.com&quot;&gt;feel free to comment&lt;/a&gt; on feedback, style, etc., as I&amp;#39;m looking to create these posts on a somewhat regular cadence.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Steve Yegge and Grok</title>
   <link href="http://bsumm.net/2012/08/11/steve-yegge-and-grok.html"/>
   <updated>2012-08-11T00:00:00-07:00</updated>
   <id>http://bsumm.net/2012/08/11/steve-yegge-and-grok</id>
   <content type="html">&lt;p&gt;Steve Yegge, best known for his long-winded and colorful articles on software engineering (and for the &lt;a href=&quot;http://articles.businessinsider.com/2011-10-12/tech/30269535_1_google-engineer-googler-google-platform&quot;&gt;fairly recent &amp;quot;public&amp;quot; posting lamenting the state of internal tools at  Google&lt;/a&gt;, posted another today as a thought experiment around &lt;a href=&quot;https://plus.google.com/u/0/110981030061712822816/posts/KaSKeg4vQtz&quot;&gt;conservatism and liberalism in programming language design&lt;/a&gt;. All thoughts aside, I found the debate to be an enlightening one in that it&amp;#39;s a topic the software community has historically underprivileged: treating software as a social construct that should be studied as one. I like to think about the success of programming languages through this lens, and arguably successful programming language designers do as well: see Larry Wall&amp;#39;s &lt;a href=&quot;http://www.linuxjournal.com/article/2070&quot;&gt;motivation for Perl&lt;/a&gt;, or Matz&amp;#39;s for Ruby (beauty, simplicity). For as much as people can disagree with the assessment Steve places on individual languages&amp;#39; ranking in his spectrum, the fact that &lt;em&gt;he ranked them&lt;/em&gt; in a public post so clearly demonstrates to me his genius in understanding that people&amp;#39;s egos are attached to the programming languages they use. I should also add that he should be in a position of understanding how people use software in the large, as he (currently?) works on tooling at Google, and previously at Amazon.&lt;/p&gt;

&lt;p&gt;The most interesting part of the aforementioned article was his mention of the &amp;quot;Grok&amp;quot; project, one which I&amp;#39;ve heard a little about through a &lt;a href=&quot;http://www.youtube.com/watch?v=vKmQW_Nkfk8&quot;&gt;few&lt;/a&gt; of his public appearances. As I searched for more information, it became clear to me that this was something he had been working on internally at Google for some time, and if I were to be more bold, I would suggest that this indeed was the very idea that he pitched internally to Bezos back when he worked at Amazon. &lt;/p&gt;

&lt;p&gt;So what is Grok? I&amp;#39;ll &lt;a href=&quot;https://plus.google.com/u/0/110981030061712822816/posts/KaSKeg4vQtz&quot;&gt;quote directly&lt;/a&gt; from the man himself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The project&amp;#39;s sole purpose in life is to bring toolchain feature parity to all languages, all clients, all build systems, and all platforms. My project is accomplishing this lofty and almost insanely ambitious goal through the (A) normative, language-neutral, cross-language definitions of, and (B) subsequent standardization of, several distinct parts of the toolchain: (I) compiler and interpreter Intermediate Representations and metadata, (II) editor-client-to-server protocols, (III) source code indexing, analysis and query languages, and (IV) fine-grained dependency specifications at the level of build systems, source files, and code symbols.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yegge&amp;#39;s ambition is to improve the state of toolchain support for &lt;em&gt;all&lt;/em&gt; editors, in a uniform way, to the point where we can simply plug in the appropriate autocomplete, definition finding logic, etc., rather than coding up from scratch each time someone implements an IDE.&lt;/p&gt;

&lt;p&gt;This would a great benefit to desktop-based development systems, but more importantly, I think it would be an amazing feature for the plethora of &amp;quot;cloud&amp;quot; editors entering into the space today (see &lt;a href=&quot;http://c9.io&quot;&gt;Cloud9 IDE&lt;/a&gt;, &lt;a href=&quot;http://chaoscollective.org/projects/builtinspace.html&quot;&gt;Space&lt;/a&gt;), as they would be able to focus on providing a great UX experience while not having to burden themselves with the language support problem. Language tooling was part of the reason TextMate 2, for instance, took so long to build.&lt;/p&gt;

&lt;h2&gt;What we know&lt;/h2&gt;

&lt;p&gt;The project started work in earnest at Google 4 years ago (2008). This aligns with a &lt;a href=&quot;http://www.cs.indiana.edu/%7Erpjames/&quot;&gt;researcher&amp;#39;s resume&lt;/a&gt; where he mentions he worked on the project in 2008 in Kirkland (outside Seattle, and home of Costco!). It went through many phases: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...in four years, from &amp;quot;VC funding&amp;quot; to &amp;quot;acceptance&amp;quot; to &amp;quot;cautious enthusiasm&amp;quot; to &amp;quot;OMG all these internal and even external projects now depend critically on us.&amp;quot;
The project is still based at Google Kirkland. It grew from 3 engineers, 6 20%ers (2010) to 6 engineers (time unknown) to 12 engineers (present). At one point, they open sourced the Java-based Python indexer used on the project (&lt;a href=&quot;http://bugs.jython.org/issue1541&quot;&gt;incorporated into Jython&lt;/a&gt;). It &lt;em&gt;used&lt;/em&gt; to be publicly available as Google Code Search, but was &lt;a href=&quot;http://codesearch.google.com/&quot;&gt;removed&lt;/a&gt; in October 2011. (This happens to coincide with his leaked &amp;quot;platform&amp;quot; memo... Coincidence?). A front-end is still publicly available, albeit only for the &lt;a href=&quot;http://code.google.com/p/chromium/source/search&quot;&gt;Chromium source base&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most information on the project I could find was a &lt;a href=&quot;http://vimeo.com/16069687&quot;&gt;video of a talk&lt;/a&gt; he did at the Northwest C++ user&amp;#39;s conference in 2010. &lt;em&gt;Disclaimer:&lt;/em&gt; this talk is nearly two years old at this point, so the project has clearly gone through a number of iterations since this came out. I&amp;#39;ve gone and written up a loose transcription of the talk, as I haven&amp;#39;t seen much else written about it elsewhere. This is all from the slides and his dialogue, but shouldn&amp;#39;t be construed as direct quotes in any case. With that being said:&lt;/p&gt;

&lt;h2&gt;Grok&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: the &lt;a href=&quot;http://vimeo.com/16069687&quot;&gt;original video&lt;/a&gt; is available on Vimeo.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yegge&lt;/em&gt;: Originally pitched at Amazon, now working on this full time at Google.
Came from learning how to deal with gigantic codebases; 50M lines or more. &lt;/p&gt;

&lt;h3&gt;Motivation&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Every company uses N &amp;gt;= 3 languages&lt;/em&gt;. In practice, they would use 15 without admitting it. SQL, devops might use Ruby to instrument their tests, etc. In production, they might only use 3, but all for different reasons.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Engineers refuse to switch editors / IDEs.&lt;/em&gt; Once an Emacs user, always an Emacs user. Many Googlers use Emacs or VIM as their primary development environment, with the Java programmers using primarily IntelliJ.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Only compilers &amp;quot;know&amp;quot; languages&lt;/em&gt;. All non-compiler languages are ad-hoc. If it&amp;#39;s not built into the IDE, it&amp;#39;s probably not widely (pervasively) used, and you get into the problem where some people are more productive than others due to the tools they choose to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Language matrix problem&lt;/h3&gt;

&lt;p&gt;Given N langauges and M editors / IDEs, total toolchain effort is N * M... Any toolchain support for this number of systems is non-trivial. For example, Emacs: &lt;em&gt;cc-engine.el&lt;/em&gt; is a huge number of lines of code, and is almost entirely for &lt;em&gt;indentation&lt;/em&gt;. This gets replicated for every language out there. &lt;/p&gt;

&lt;p&gt;How do you solve matrix problems like this? Use a hub and spoke model.&lt;/p&gt;

&lt;h3&gt;Grok: a Language-to-client Hub&lt;/h3&gt;

&lt;p&gt;Moving from matrix to a hub-and-spoke model for editors. Eclipse, and every IDE implementor failed software engineering 101: separate the indexer from the GUI platform. There should be a clean separation from the autocomplete from the GUI portion.&lt;/p&gt;

&lt;p&gt;Each IDE becomes a &amp;quot;thin&amp;quot; client. Every IDE supports M languages out of the box.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side benefits:&lt;/em&gt; Eclipse will start faster (less tooling support needed). Consistency across cross-language calls. &lt;/p&gt;

&lt;p&gt;Crucially, consistent tools make it easier to switch languages. Devs would then be more likely to use the best language for the job. IDE authors can focus on presentation and editing. This leads to more configurability, scriptability, accessibility in languages.&lt;/p&gt;

&lt;h3&gt;Additional languages&lt;/h3&gt;

&lt;p&gt;Why do people choose Java? It&amp;#39;s not because of Java the language. C++ was heavily marketed by Bell Labs, AT&amp;amp;T (90&amp;#39;s). Sun chose to pump millions of dollars into Java. Two things: tools and performance.&lt;/p&gt;

&lt;p&gt;Think that they&amp;#39;re choosing a language based on type system, etc. There&amp;#39;s a whole class of problems that aren&amp;#39;t handled by this (runtime problems and the &lt;em&gt;NullPointerException&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;If a language isn&amp;#39;t successful, it&amp;#39;s because the tools aren&amp;#39;t good enough. Through interviews with hundreds of people, online comments, and talks: it always comes down to the tools.&lt;/p&gt;

&lt;p&gt;The economy of the game market is actually forcing to  switch the language: they need to use Lua to the logic. Bigger companies don&amp;#39;t have the same economics in other fields -- people will tend to write everything in one language. If you&amp;#39;re writing something to be run once, you should be using a language made for doing quick scripting tasks, rather than trying to implement these tools in a systems language. &lt;/p&gt;

&lt;h3&gt;How do we do it?&lt;/h3&gt;

&lt;p&gt;Compiler writers don&amp;#39;t care about these things: they want things to be correct, fast. 
Typically make a IR, then almost immediately get rid of all this information to convert to bytecode, etc.
Why do we have two compilers, one for codegen vs. the toolchain? For the most part, they don&amp;#39;t want to combine them because they have slightly different goals. &lt;/p&gt;

&lt;p&gt;Idea: pry open compilers, run their &amp;quot;guts&amp;quot; on distributed clusters, output  a language neutral index. Serve the index via service APIs. Write client plugins, etc.&lt;/p&gt;

&lt;p&gt;Clang makes this easy to do. &lt;/p&gt;

&lt;h3&gt;How we analyze languages&lt;/h3&gt;

&lt;p&gt;First use case: create LXR-like environment for Java. &lt;em&gt;ctags&lt;/em&gt; is &lt;em&gt;basically&lt;/em&gt; a regexp-based library. Had to fork Eclipse, but all the code was complected with the indexer and the GUI as previously mentioned. Existing tools use a combination of methods for tooling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;C++: Eclipse CDT (soon to be Clang)&lt;/em&gt; use a reference graph&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Java: Eclipse JDT&lt;/em&gt; builds up IR for IDE use cases: diagnostics, errors, warnings, type graphs. Internally, has a reference graph for callers, callee. &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Python&lt;/em&gt;: bottom-up, top-down type inferencers, and tended to work quite well for our use cases. We &lt;a href=&quot;http://bugs.jython.org/issue1541&quot;&gt;opened sourced the Python indexer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;JavaScript&lt;/em&gt;: Google&amp;#39;s JSCompiler (Closure) for type inferences, etc. This in practice made the job much easier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The issue is often, when people have a language problem, they tend to want to write some stupid regexp parser. The thought is that parsing is hard. In practice, name resolving and type resolution is 80,90% of the problem... but people never realize that until they&amp;#39;ve implemented the parser already. So people think parsing is the difficult thing. Many people take the approach the wrong way. &lt;/p&gt;

&lt;p&gt;The goal of Grok is not to write a parser. We don&amp;#39;t want to reinvent the wheel. For in-house languages we instrument the compiler / interpreter.&lt;/p&gt;

&lt;h3&gt;Goal: get compiler writers to give us this information&lt;/h3&gt;

&lt;p&gt;The idea is to put peer pressure on the language / compiler vendors community (ultimately the ones to generate or interpret all the metadata of languages and are the ones in the best position to instrument their software properly). People will start to expect &amp;quot;Grok&amp;quot; support in their editors.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anecdote:&lt;/em&gt; MS to Google people often complained that code exploration will really poor, coming from the world of Intellisense and Visual Studio. &lt;/p&gt;

&lt;p&gt;After doing some research, we realized that people often asked for, essentially, SQL support for doing queries on languages... In other cases, they might want sort of an XPath,  hierarchical query support. In other contexts, they might also want to treat code as a graph problem. Desired features would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Code navigation and browsing&lt;/em&gt;: Jump to decl,def,show xrefs, outlines, ..&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Interactive editing&lt;/em&gt;: Indent, reformat, autocomplete symbols...&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Queries&lt;/em&gt; (e.g., find subclasses of C where X)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Static analysis (e.g., find memory leaks)&lt;/em&gt;: Example question: find out how to use exception handling in Java. Want to prove statically-checked exceptions are useless 98% of the time. Now we can do this easily, as we can grep for these things across the entirety of the code base.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Language-neutral index&lt;/h3&gt;

&lt;p&gt;This is really a key-value store, a multimap. Every identifier gets a key (globally unique).  &lt;em&gt;C++&lt;/em&gt; names aren&amp;#39;t necessarily global in any case. Have to invent a global namespace by depot, etc.&lt;/p&gt;

&lt;p&gt;From our observations, every file generates 100x its file size in metadata. Implementation thus far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modeled loosely on Eclipse&amp;#39;s IR: Nodes (&amp;quot;bindings&amp;quot;) for decls/defs/refs; Typed edges (&amp;quot;associations&amp;quot;) between nodes&lt;/li&gt;
&lt;li&gt;Example association kinds: &lt;em&gt;SUBCLASS_OF&lt;/em&gt;, &lt;em&gt;SUBCLASS_OF&lt;/em&gt;, &lt;em&gt;CALLED_BY&lt;/em&gt;, &lt;em&gt;IMPLEMENTS&lt;/em&gt;, &lt;em&gt;ENCLOSING_SCOPE&lt;/em&gt;, &lt;em&gt;FIELD_OF&lt;/em&gt;, &lt;em&gt;DEPENDS_ON&lt;/em&gt;, &lt;em&gt;INCLUDES&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;em&gt;sorta&lt;/em&gt; language neutral. Some languages don&amp;#39;t have classes; instead they have functions, variables. Each time we go through the data model we find new mappings for new languages. In practice, every single abstraction in this edge has at least 2 languages using it: symbols are used the same in Lisp as in Ruby, for example.&lt;/p&gt;

&lt;h3&gt;Cultural challenges&lt;/h3&gt;

&lt;p&gt;Even if you deliver this beautiful thing, there&amp;#39;s still a lot of cultural problems in getting something out there successfully. (&lt;em&gt;audience:&lt;/em&gt; Someone should&amp;#39;ve done this 30 years ago. &lt;em&gt;Yegge:&lt;/em&gt; Someone &lt;em&gt;did do&lt;/em&gt; this already in Smalltalk, but it was only for that specific dynamic language.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Adoption&lt;/em&gt;: hard to get devs to use new tools. It&amp;#39;s hard to retrain myself to click links rather than grep for everything. At Google, it&amp;#39;s well-known that fancy new tools have a slow adoption curve. Google ranks you on how adoption is going.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Speed vs accuracy&lt;/em&gt;: Grok&amp;#39;s philosophy is that some data is often better than none. On the other hand, Eclipse doesn&amp;#39;t scale well for Google-size code bases. Autocomplete sometime halts the entire process when a seemingly simple dependency changes. Doing this remotely is still a tradeoff, as some programmers don&amp;#39;t deal well with eventual consistency in their tooling -- some people complain that immediate consistency is crucial to prevent them from building things incorrectly. Java programmers are often expecting 100% IDE accuracy, and this is a cultural expectation.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Prioritization&lt;/em&gt;: companies never want to staff this kind of effort.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Managing expectations&lt;/em&gt;: Engineers hear about this project and they want it yesterday. There&amp;#39;s no good elevator pitch for this kind of thing, but if you sit down with them for 15 / 20 minutes, they will &lt;em&gt;want&lt;/em&gt; it at that point. Now, you have to manage expectations. If you promise everything, you&amp;#39;ll never be able to meet people&amp;#39;s immediate expectation of the thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Clang @ Google&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clang enables modern C++ tools on Linux (finally!). Fast, smart, efficient, usable (all of which CDT is not). There was a lot of work to make it work properly.&lt;/li&gt;
&lt;li&gt;Google&amp;#39;s main code base is recently Clang parse-clean. Chromium can be built with Clang.&lt;/li&gt;
&lt;li&gt;An internal clang team at Google is devoted to supporting Clang tools: IDE support, indexing, search, refactoring, analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(GCC folks have been late to the game with toolchain support. Stallman is afraid of other people wresting control of the project from him -- which is based in reality, as many companies tried to do so.) This ended up causing poor tooling support.&lt;/p&gt;

&lt;h3&gt;See Grok in Action&lt;/h3&gt;

&lt;p&gt;Grok indexes Chromium + WebKit source code currently. The indexer was contributed entirely as a 20% project. We serve Grok index data to Google Code Search.
- Currently only &lt;a href=&quot;http://code.google.com/p/chromium/source/search&quot;&gt;Chromium is externally visible&lt;/a&gt;. In any source file, hover over indentifiers. Can also show cross-refs (bottom of the page)&lt;/p&gt;

&lt;p&gt;Long-term we would like to be able to Grok all open-source code in the world. For any given Java library in the world, find all callers of this function!&lt;/p&gt;

&lt;p&gt;Biggest problem is that we&amp;#39;re really tied to Google&amp;#39;s build system. Critically tied to finding information about build paths, Make, ant, etc... This is something we&amp;#39;d have to rearchitect for publishing out in the open. &lt;/p&gt;

&lt;h3&gt;What we&amp;#39;ve built so far&lt;/h3&gt;

&lt;p&gt;Team of 3 in Kirkland, plus six 20% contributors. We support C++/Java/Python/JS and 2 internal languages. Open-sourced our Python indexer (jython.org). Mostly support Browser/Navigation + simple queries. Flagship clients are Emacs and Code Search. We started work on interactive use case static analysis.&lt;/p&gt;

&lt;h3&gt;Open-source / open platform&lt;/h3&gt;

&lt;p&gt;Grok isn&amp;#39;t easily / directly open-sourceable. Our indexes and protocols are all internal formats. We also rely heavily on Google&amp;#39;s internal build system. The long-term goal is be an external platform and with open standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardize expected set of compiler artifacts&lt;/li&gt;
&lt;li&gt;Standardize schemas (MySQL / NoSQL / XML, etc)&lt;/li&gt;
&lt;li&gt;Standardize the services for clients&lt;/li&gt;
&lt;li&gt;Open-source our analyzers and plugins as example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At some point, it would be nice to have people convert their standard IR formats to Grok using tools.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>WYSIWYG and merging</title>
   <link href="http://bsumm.net/2012/08/05/wysiwyg-dvcs.html"/>
   <updated>2012-08-05T00:00:00-07:00</updated>
   <id>http://bsumm.net/2012/08/05/wysiwyg-dvcs</id>
   <content type="html">&lt;p&gt;I just read &lt;a href=&quot;http://www.joelonsoftware.com/items/2010/03/17.html&quot;&gt;Joel Spolsky&amp;#39;s take&lt;/a&gt; on distributed version control. He states the most important thing about Git is that it forces people to think in terms of changes, not versions. As in, bring in Mary&amp;#39;s change, bring in his change, as opposed to everyone working towards some base version. GitHub takes this idea and turns it into a service.&lt;/p&gt;

&lt;p&gt;However positive this leap may be, it tends to cause &lt;a href=&quot;http://news.ycombinator.com/item?id=4340047&quot;&gt;usability issues&lt;/a&gt; for those using it. When dealing with merging, there&amp;#39;s the essential complexity of merging -- that is, merging in changes from multiple sources into working code, and trying to suss out how to deal with the semantics of two changes to a piece of software. This is separate from the accidental complexity of the CLI, documentation, the bevy of tools, the mental model of the Git runtime, etc., which people tend to find so difficult, especially for single-person use cases.&lt;/p&gt;

&lt;p&gt;I suspect GitHub&amp;#39;s desktop apps were created to alleviate this usability issue. In simple cases, much of this merging complexity can be transparent to users, and the system could do much of the merging automatically. When dealing with programming / markup languages, this doesn&amp;#39;t in pratice work very well, as the strictness of the compiler and the language&amp;#39;s syntax tries to &lt;em&gt;remove&lt;/em&gt;  all ambiguity. Git, being the &amp;quot;stupid&amp;quot; versioning system it is, doesn&amp;#39;t get in the way of this process. Manual merges are the human-powered mechanism for ensuring that whatever is written down is exactly is what is intended by the author.&lt;/p&gt;

&lt;p&gt;In other media, though, ambiguity in merges isn&amp;#39;t a big deal, especially when dealing with non-procedural languages. When merging graphics layers in Photoshop, there&amp;#39;s basically no possibility of conflict in global state, so people are able to copy paste pretty readily. (In practice, I think this might not be entirely true, as there&amp;#39;s probably some dependencies on global settings like bit depth, gamut, etc.)&lt;/p&gt;

&lt;p&gt;Tracking document changes in Word is another example of VCS that happens to be quite usable for its problem domain. Seeing the main DVCS princple (changes, not versions!) applied to a WYSIWYG editor, visual or textual, would be interesting. This is basically where Google Wave was heading.&lt;/p&gt;

&lt;p&gt;For certain domains, I would like to see an abstracted editor, using Git internally, that makes it totally opaque to the user when commits are occuring. This would be basically equivalent to an undo / redo command history, but with the additional ability for you to bring in others&amp;#39; history in with yours. &lt;/p&gt;

&lt;p&gt;Again, this all entails a medium receptive to ambiguous changes, so systems language programming would probably be a bad fit for this. I would expect this would be most useful in the context of GUI programming and front-end development, where merges can be as simple as dragging and dropping. The traditional difficulty of forming abstractions with a visual medium (at least compared to textual programming languages) fortunately makes it that much easier to adapt to a new model of merging changes.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>In defense of Flash 4</title>
   <link href="http://bsumm.net/2012/07/17/flash.html"/>
   <updated>2012-07-17T00:00:00-07:00</updated>
   <id>http://bsumm.net/2012/07/17/flash</id>
   <content type="html">&lt;p&gt;When discussing Adobe Flash, it&amp;#39;s important to separate out &lt;em&gt;Flash&lt;/em&gt;, the IDE, from Flash Player, the vilified web runtime. The former I&amp;#39;ll forever have a soft spot for, as it arguably influenced my becoming  the programmer I am today. &lt;/p&gt;

&lt;p&gt;When people talk about hating Flash, they typically mean the runtime, and all the baggage that goes along with it: its fan-inducing, CPU-devouring ineffectiveness, its perky installer windows that always seems to appear whenever you least expect it, etc. We&amp;#39;ve come to expect better of our runtimes in this day and age. Steve Jobs&amp;#39; &lt;a href=&quot;http://www.apple.com/hotnews/thoughts-on-flash/&quot;&gt;Flash letter&lt;/a&gt; spells out clearly why we don&amp;#39;t have Flash on iOS today: its proprietary nature, its security record, performance, battery life, and the fact that it wasn&amp;#39;t designed for touch input. Except for the final issue, these are all failings of the virtual machine. Flash, as a platform, has failed to meet the expectations of its consumers, and rather than supporting this sub-par experience, Apple chose to kill it off. That&amp;#39;s that.&lt;/p&gt;

&lt;p&gt;But with the eventual demise of the Flash ecosystem, let us not forget Flash, the editor, especially in its early forms. It was and is one of the most successful multimedia creation tools for the web. It&amp;#39;s interesting to think about why this was. I suspect it was partially because it enabled those without any traditional programming experience to create quite sophisticated web sites and animations. Arguably, this was ultimately because it had an intuitively designed user interface.&lt;/p&gt;

&lt;p&gt;I confess: when I was in elementary school, I had an obsession with Pokémon. I had basically memorized the official guidebook to the series -- I had read it so many times the cover had come clear off. Of course, I wasn&amp;#39;t alone in my fascination with this Nintendo cash cow. All of the best Pokémon fan pages on the Internet had these over-the-top animated fight sequences as their splash intros, which I thought was the coolest thing ever. Along the way, I eventually  &lt;em&gt;acquired&lt;/em&gt; a copy of Flash 4 when I realized this was the software everyone had used to make these great scenes. Before I knew it, or knew that programming even existed as a profession for that matter, I was animating my meticulously hand-drawn vector Squirtles across timelines with only the most cursory knowledge of how animation software actually worked. Mind you, at that time, you were &lt;em&gt;encouraged&lt;/em&gt; to do everything using a GUI interface, and for most part it handled things quite well. Over the course of a year, I got more ambitious: minute-long action sequences with sound; dancing Pikachus set to the music of Saturday Night Fever; parallax shoot-em-ups made without any real working knowledge of &lt;em&gt;variables&lt;/em&gt;. Did I know the inheritence hierarchy of buttons or movie objects, or care about the difference between bitmap or vector graphics? No. All I knew was that I had a vision, and this was giving me some pretty convincing results.&lt;/p&gt;

&lt;p&gt;Eventually, I started using event-handlers, learning for the first time how to assign commands to mouse events using Actionscript. I remember this being by far the most frustrating part of the process, as I didn&amp;#39;t ever take the time to read documentation for the thing (as if that should ever be a problem). To me, Actionscript was a band-aid, a set of indecipherable hieroglyphics grafted onto this amazing playground of visual fun. I remember painfully learning what a compilation step was, and wondering if the thing I had just typed up was actually going to do what I wanted it to. I remember cryptic errors leading to abandoned ideas. I remember &lt;a href=&quot;http://martinfowler.com/bliki/TwoHardThings.html&quot;&gt;solving the second hardest problem&lt;/a&gt; in computer science: naming things, because you needed to script objects on screen. I remember it wasn&amp;#39;t as fun, more than anything else.&lt;/p&gt;

&lt;p&gt;I was realizing the possibilities &lt;em&gt;and&lt;/em&gt; the frustrations caused by using an abstract, textual form when interacting with my graphics. With subsequent versions of Flash, it was as if this style had taken over. Best practices now recommended reading the spec for this new, adult Actionscript: a gargantuan, unholy Javascript and XML lovechild, filled with serious object-oriented programming constructs, and all sort of other paradigms completely foreign to me. To make a button before, you had to add actions to its &amp;#39;click&amp;#39; marker on a timeline. With Actionscript, I had to think of my button as a living, breathing object, with event handlers for each of the possible touch states I wanted to work with. I had to straddle two mental models of the thing before I was even allowed to think of doing the kind of animation work I once had. Frankly, I was lost in this world. While others found the challenge of a blank text field exhilarating, my young self found better things to do. With the maturation of Actionscript, the role of the programmer was emphasized over the graphic artist and animator. Flash, the IDE, had effectively said I was no longer its target consumer. &lt;/p&gt;

&lt;p&gt;Flash 4 was the beginning for me. I think back to how formative this was in my later thinking about computers; how it gave me the confidence to know that I was indeed capable of making complex animations, and how creating on a computer could be as, if not more, rewarding than any pen-to-paper drawing experience. All this &lt;em&gt;without&lt;/em&gt; needing to type a single line of code. As I read back on the &lt;a href=&quot;http://www.flashmagazine.com/news/detail/the_flash_history/&quot;&gt;history of Flash&lt;/a&gt;, it&amp;#39;s interesting to see its evolution from a seemingly trivial drawing application to the highly-advanced development environment it is today. Somewhere along the way Macromedia set its sights on a more serious customer. Did their developers realize what they had created in the first place?&lt;/p&gt;

&lt;p&gt;More features does not a better product make. When I see a dearth of &lt;em&gt;simple&lt;/em&gt; creational software today, and especially with the iPad in the hands of so many children, I wonder why where there isn&amp;#39;t a more concerted effort in making products that even children can be productive with, like Flash 4. Flash&amp;#39;s focus on simplifying animation and interactions got an elementary school kid to make some awesome stuff, some of which would still be difficult for your run-of-the-mill college hire to do in other mediums -- and all because there was a tool with the right abstractions. How shortsighted are we to assume that that we should be teaching everyone &amp;quot;real&amp;quot; programming à la Codecademy or Lua via the iPad app Codea, as if typing programming languages into a terminal was the only valid way to create on a computer. Let&amp;#39;s spend some time thinking about how to re-imagine our own tools and languages to serve the jobs of a diverse set of people, even if it means underserving the most technical for a change. In the process, maybe we give some other kids a glimpse at their potential future selves.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Papert's Mindstorms</title>
   <link href="http://bsumm.net/2012/07/01/mindstorms.html"/>
   <updated>2012-07-01T00:00:00-07:00</updated>
   <id>http://bsumm.net/2012/07/01/mindstorms</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;/images/mindstorms.jpg&quot; style=&quot;height: auto; width: 195px; margin: 15px; float: right;&quot;&gt;&lt;/p&gt;

&lt;p&gt;Alan Kay cites Seymour Papert&amp;#39;s 1980 thesis &lt;em&gt;Mindstorms&lt;/em&gt; so frequently that I figured would eventually have to read it. A few weeks ago, I picked up the revised 1993 edition. Today, educators and technologists tend to emphasize marketplaces and apps, the &lt;em&gt;what&lt;/em&gt;, as solutions to educational issues. Few argue for radical changes both in medium and pedagogy, the &lt;em&gt;what&lt;/em&gt; and the &lt;em&gt;how&lt;/em&gt;. Papert believed this was key. In predicting the rise of the personal computer, he developed a cohesive vision of &lt;em&gt;children teaching computers&lt;/em&gt; as the basis for a new digital pedagogy, based on his novel theory of &lt;em&gt;constructionism&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Papert&amp;#39;s studied with Jean Piaget for over 6 years, and was famously precocious. Piaget once said, &lt;a href=&quot;http://en.wikipedia.org/wiki/Constructivism_(learning_theory&quot;&gt;&amp;quot;no one understands my ideas as well as Papert&amp;quot;&lt;/a&gt;. His most important insight was in how people, and especially children, accumulate knowledge experientially. Piaget concluded that children were capable of abstractions at an early age. The difference between adult reasoning was that these were primitive models, learned through experimentation, and were constantly changing with new experiences. &lt;em&gt;Genetic epistemology&lt;/em&gt; described this process of accumulated learning. Recently, this has been linked as the probable function of own neurons.&lt;/p&gt;

&lt;p&gt;Papert strongly believed in using experiential learning as a foundation for further, more traditional abstract learning. A mathematician by training, he believed that children using the right &lt;em&gt;object-to-do-with&lt;/em&gt;, along with appropriate teacher-as-peer guidance, could help develop mental models of mathematical concepts at a very early age. This informed his &lt;a href=&quot;http://wiki.laptop.org/go/Constructionism&quot;&gt;theory of constructionism&lt;/a&gt;. Papert summarizes experimentation-as-learning as &lt;em&gt;syntonic&lt;/em&gt;. This is to be contrasted with more traditional &lt;em&gt;disassociated&lt;/em&gt; learning, which emphasizes learning abstractions, then its applications. &lt;/p&gt;

&lt;p&gt;Math education in the US is still largely taught using the disassociated model. This tends to disengage students, as they can neither empathize nor apply it to their own lives. He believed this caused our national mathphobia, as generations of parents traumatized by New Math instilled this same learned helplessness in their children.&lt;/p&gt;

&lt;p&gt;He stressed teachers act as cultural anthropologists, keeping abreast of cultural trends to ensure using relevant mediums in children&amp;#39;s lives. He believed that the keys to successful teaching was in making material meaningful and relevant to students. In practice, this could be accomplished by finding relationships to previous experiences in their lives, and building on that knowledge as a model. He gives a personal anecdote to demonstrate this idea: as a child, he loved gears, and the differential axle in particular. He saw how the two axles could move independent of each other while the drivetrain distributed power accordingly. After awhile, he was able to visualize their motions in his mind&amp;#39;s eye. When it finally came time to learn symbolic algebra in grade school, he had little difficulty in intuiting the relationship between variables in an equation, as he already had a working model of these gears in his head. For instance, given:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;text&quot;&gt;ax + by = 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;a&lt;/code&gt;  and &lt;code&gt;b&lt;/code&gt; could represent constant ratios of our wheel gears, and &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; the rotational velocities of a given wheel&amp;#39;s axle.&lt;/p&gt;

&lt;p&gt;Papert later became a professor at MIT, and spoke with the likes of Marvin Minsky regularly. As such, he was able to accurately predict the age of the personal computer. He was an optimist, and believed that this could also radically change education:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] the computer presence will enable us to so modify the learning environment outside the classroom that much if not all the knowledge schools presently try to teach with such pain and expense and such limited success will be learned, as the child learns to talk, painlessly, successfully, and without organized instruction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Important to note is that Papert thought of the computer as &lt;em&gt;disruptive&lt;/em&gt; rather than &lt;em&gt;complementary&lt;/em&gt; to our educational system. Thirty years later, we haven&amp;#39;t seen the incorporation of a pervasively digital pedagogy. (This could be partially explained by the scarcity of engineers and scientists in administrative and educational leadership positions.) Rather, the focus has been on adapting existing curriculum to digital forms. For example, the Khan Academy promotes blended learning classroom models, where short-form video lessons are supplemented by teacher intervention.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(1) significant change in patterns of intellectual development will come about through cultural change, and (2) the most likely bearer of potentially relevant cultural change in the near future is the increasingly pervasive computer presence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Perhaps Papert overestimated the speed of cultural change, thinking it could keep pace with technology. His knowledge of cultural change came from his wife, Sherry Turkle, who spent time researching the French&amp;#39;s adoption of psychoanalysis. Cultural choices tend not to change once a path has been taken, no matter how suboptimal it becomes as time goes on. Change tends to occur over &lt;em&gt;generations&lt;/em&gt;, rather than decades. In turn, disruptive ideas are discarded in favor of incremental progress. Many examples of this occur in life: Kuhn&amp;#39;s &lt;em&gt;The Structure of Scientific Revolutions&lt;/em&gt; describes this phenomenon as it pertains science research. Papert cites the &amp;quot;QWERTY phenomenon,&amp;quot; where the arrangement of letters on a keyboard is more due to historical artifact more than critical reasoning. Alan Kay describes computer science today as an incremental pop culture in &lt;a href=&quot;https://www.tele-task.de/archive/video/flash/14029/&quot;&gt;&amp;quot;Programming and Scaling&amp;quot;&lt;/a&gt;, and offers guidance on how to avoid this default mode of thinking.&lt;/p&gt;

&lt;p&gt;Other roadblocks abound. Experiential learning is realized differently for every individual, and this is at odds with an idealized curriculum. Papert argues objective curriculums are a panacea, as best practices are always relative to a given culture and technology. For example, analytical geometry, typically taught in high school, is done so for historical reasons: only at that point in school can fine motor skills be assumed enough to draw graphs using pen and paper. Today, the merits of cursive is questioned in a world of keyboards and touch screens.&lt;/p&gt;

&lt;p&gt;Today&amp;#39;s emphasis on summative assessments, coupled with an incentive to teach to the test, point towards an even more idealized curriculum than before. This poses significant problems in more fully realizing Papert&amp;#39;s ideas in US classrooms. On the other hand, his vision has seen acceptance in other forms. The One Laptop Per Child project&amp;#39;s motivational theory was based on constructionism, and is in millions of classrooms worldwide. LEGO Mindstorms, named after the book, along with its corresponding robotics competitions, emphasizes experiential learning by programming LEGO bricks. The MIT Media Lab was originally created as a center of epistemological research, initially focused on exploring  Papert&amp;#39;s own principles. Of course, Papert also developed LOGO, an &amp;quot;exploratory mathematical sandbox&amp;quot; and &lt;em&gt;object-to-do-with&lt;/em&gt; to help children intuit mathematical concepts. In an upcoming essay, I&amp;#39;ll dive into LOGO&amp;#39;s programming model, and look to use it as a lens into educational software as a whole today.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Old projects</title>
   <link href="http://bsumm.net/2012/06/25/old-projects.html"/>
   <updated>2012-06-25T00:00:00-07:00</updated>
   <id>http://bsumm.net/2012/06/25/old-projects</id>
   <content type="html">&lt;p&gt;I&amp;#39;m doing some spring cleaning on the site. If you&amp;#39;re interested in music synthesizers for iOS, see the project pages for &lt;a href=&quot;/projects/ijam.html&quot;&gt;iJam&lt;/a&gt; or &lt;a href=&quot;/projects/pdlib.html&quot;&gt;pdlib&lt;/a&gt;. Otherwise, stay tuned for future updates.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Holistic views of nearly everything</title>
   <link href="http://bsumm.net/2010/10/14/a-holistic-view-of-nearly-everything.html"/>
   <updated>2010-10-14T00:00:00-07:00</updated>
   <id>http://bsumm.net/2010/10/14/a-holistic-view-of-nearly-everything</id>
   <content type="html">&lt;p&gt;Finding connections between disciplines fascinates me, like the similarities between &lt;a href=&quot;http://www.paulgraham.com/hp.html&quot;&gt;work habits of hackers and painters&lt;/a&gt;. The benefits of extracurricular research in unrelated fields aren&amp;#39;t always immediately realized, but this gain in perspective can lead to many long-term benefits. Lateral thinking and creativity depend on the ability to adapt processes and metaphors to something else. Regarding my ideal university experience, I advocate that engineering majors invest substantial time in studying humanities.&lt;/p&gt;

&lt;p&gt;Analytical and procedural thinking are requisites for any successful computer scientist, but the truly innovative are able to call on a wide breadth of knowledge when needed. This can have surprising results. &lt;a href=&quot;http://en.wikipedia.org/wiki/John_Henry_Holland&quot;&gt;John Holland&lt;/a&gt; took the idea of gene replication and adapted it into a well-known algorithm. Alan Kay, trained as a biologist, took the idea of cellular processes as the basis for object-oriented programming: encapsulation serving as an analogue to the cell wall, and signaling between the cells representing something akin to message passing. Understanding the incentives of your customer is largely about being able to empathize with them. As Google has demonstrated, this can&amp;#39;t always be solved by refining an algorithm or A/B testing. This realization has led to technology companies emphasizing interaction design, which has its roots in  psychology. Systems thinking, now commonly applied in business development, was largely inspired by the work of Donella Meadows, an environmental scientist who wrote 1972&amp;#39;s the &lt;a href=&quot;http://www.amazon.com/Limits-Growth-30-year-Update/dp/184407143X&quot;&gt;The Limits of Growth&lt;/a&gt;, a study of how exponential forces interact with finite natural resources. (Another one of her books, &lt;a href=&quot;http://www.amazon.com/Thinking-Systems-Donella-H-Meadows/dp/1603580557&quot;&gt;Thinking in Systems&lt;/a&gt;, remains a favorite read of mine as a beginner&amp;#39;s guide to systems thinking.)&lt;/p&gt;

&lt;p&gt;Breadth in thinking, to me, means reading widely, critically, and then deeply in fields one finds interesting. This requires &amp;quot;learning how to learn,&amp;quot; which happens to be one of the tenants of an ideal liberal arts education. Unfortunately, this isn&amp;#39;t a focus of many engineering schools. More engineers and technologists-cum-entrepreneurs should find more time to explore these fields, not only for perspectives&amp;#39; sake, but also for the sake of our global society. &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Scheming to learn recursion</title>
   <link href="http://bsumm.net/2010/08/01/learning-recursion.html"/>
   <updated>2010-08-01T00:00:00-07:00</updated>
   <id>http://bsumm.net/2010/08/01/learning-recursion</id>
   <content type="html">&lt;p&gt;Reading &lt;a href=&quot;http://www.amazon.com/gp/product/0394756827&quot;&gt;Gödel, Escher, Bach&lt;/a&gt; broadened my perspective on recursion and the idea of the pervasiveness of composition &lt;em&gt;of&lt;/em&gt; self &lt;em&gt;with&lt;/em&gt; self. Recursion is everywhere: in the Piaget&amp;#39;s genetic epistemology, where new mental abstractions are defined by existing ones; the actual neurological structure of our brain via feedback loops, and its digital analogue in neural networks; visicious and virtuous cycles in systems thinking and economics; fractals; and also in various programming languages, especially those with lamdba calculus roots.&lt;/p&gt;

&lt;p&gt;One languages celebrating recursion is Guy Steele and Gerry Sussman&amp;#39;s Scheme, a dialect of of Lisp known for its minimal syntax and library. Scheme was created partially as a teaching aid for introductory computer science courses at MIT. Lisp, in turn, has its roots as a theoretical language in the AI Lab in the late 50&amp;#39;s. John McCarthy famously created it without intended it to be implemented; it took a student named Steve Russell to create the first interpreter. The &lt;a href=&quot;http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf&quot;&gt;LISP 1.5 Programmers Manual&lt;/a&gt;, by McCarthy himself, remarkably implements the entirety of a Lisp interpreter in a single page (see Appendix B&amp;#39;s definition of &lt;code&gt;eval&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;However, my initial interest in Lisp began with Paul Graham&amp;#39;s essays. He waxed eloquent in &lt;a href=&quot;http://www.amazon.com/gp/product/0596006624&quot;&gt;Hackers and Painters&lt;/a&gt;&amp;#39;s &amp;quot;&lt;a href=&quot;http://www.paulgraham.com/avg.html&quot;&gt;Beating the Averages&lt;/a&gt;&amp;quot;, about how business with limited labor should be using programming languages that maximize their productivity, ideally via higher-level abstractions and meta-languages. Around the same time, I picked up a copy of Daniel Friedman&amp;#39;s &lt;a href=&quot;http://www.amazon.com/gp/product/0262062178&quot;&gt;Essentials of Programming Languages&lt;/a&gt;, an academic treatise on programming language theory that assumed a working knowledge of Scheme.&lt;/p&gt;

&lt;p&gt;Rather than diving headfirst into the text, I figured it would better to start small and work my way up. What I&amp;#39;m reading now is &lt;a href=&quot;http://www.amazon.com/gp/product/0262560992&quot;&gt;The Little Schemer&lt;/a&gt;, also by Daniel Friedman. This book&amp;#39;s style is the complete opposite of &lt;em&gt;Essentials&lt;/em&gt;; it assumes no experience programming, and works as a two-way dialogue, where the reader is encouraged to programming questions along the way. The tone is absurd in the vein of &lt;a href=&quot;http://mislav.uniqpath.com/poignant-guide/&quot;&gt;Why&amp;#39;s Poignant Guide&lt;/a&gt;, with pages devoted as a tablemat for PB&amp;amp;J sandwiches. It&amp;#39;s a quick read, but worthwhile if you&amp;#39;re looking for an entertaining weekend guide to recursive thinking. &lt;/p&gt;

&lt;p&gt;It&amp;#39;s unfortunate the syntax of Lisp has been a roadblock, as its S-Expressions, enabling homoiconicity, are one of language&amp;#39;s strengths. M-Expressions, as McCarthy originally intended Lisp to be written in, were meant to provide a more familiar imperative facade to the language. This never caught on, even with valiant attempts by Apple with its Dylan language. Whether syntax is the reason, CS schools, and most famously MIT, have phased out teaching Scheme in their introductory courses. There&amp;#39;s an interesting debate about practicality of programming languages taught at the university level. Papert would argue that the first language you learn tends to influence your view of others, and in this case Scheme might be a good theoretical foundation. Python, on the other hand, has a strong resemblance to what we typically write as pseudocode, which may serve a more enlightened discourse for beginners. In any case, &lt;a href=&quot;http://lambda-the-ultimate.org/node/1840&quot;&gt;Lambda the Ultimate article&lt;/a&gt; explores the issue further. &lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Learning Perl</title>
   <link href="http://bsumm.net/2010/07/09/learning-perl.html"/>
   <updated>2010-07-09T00:00:00-07:00</updated>
   <id>http://bsumm.net/2010/07/09/learning-perl</id>
   <content type="html">&lt;p&gt;As there&amp;#39;s a decent amount of legacy code at work, I&amp;#39;m starting to learn Perl. The language has had a longer history than some of the popular scripting languages today, so determining best practices involves good ol&amp;#39; investigative work. A good starting point, I&amp;#39;ve been repeatedly told, is the mammoth (e.g. &lt;a href=&quot;http://www.amazon.com/Programming-Perl-3rd-Larry-Wall/dp/0596000278&quot;&gt;Programming Perl&lt;/a&gt;), which represents the learn-everything-at-once, disassociated approach, and favors those who would love nothing more than to curl up next to an O&amp;#39;Reilly book for an entire weekend. &lt;a href=&quot;http://www.onyxneon.com/books/modern_perl/index.html&quot;&gt;Modern Perl&lt;/a&gt;,  a more recent beginner&amp;#39;s book, which takes an opinionated view in promoting more recent changes to the language, starting with Perl 5.12.&lt;/p&gt;

&lt;p&gt;Here are a few observations I&amp;#39;ve noticed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby borrows Perl&amp;#39;s syntax more than I realized (e.g., postfix conditionals)&lt;/li&gt;
&lt;li&gt;The breadth of libraries is the most comprehensive of any language I&amp;#39;ve used. People really seem to be good about writing good documentation for their code, which is helpful. The CPAN model has since seen rapid adoption by other scripting languages with much success; see Ruby&amp;#39;s &lt;code&gt;gem&lt;/code&gt; and node.js&amp;#39; &lt;code&gt;npm&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cpanmin.us/&quot;&gt;cpanminus&lt;/a&gt; is a simpler CPAN; it works exactly how I&amp;#39;d like a package management system to work, without the bevy of features you need to configure when using the &lt;code&gt;perl -MCPAN -eshell&lt;/code&gt; CLI.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://moose.perl.org/&quot;&gt;Moose&lt;/a&gt; is an impressive object system, and includes many more meta-class features than one would typically come to expect in an OO language. Traits are another welcomed feature. Unfortuatnely, adding Moose as a dependency also tends to limits its usage in legacy contexts.&lt;/li&gt;
&lt;li&gt;Pervasive context-awareness is something that took me some time to understand, but now it seems natural. In addition, dealing with references adds another layer of complexity that can be intimidating to new users having to deal with both at the same time. This is unlike most other scripting languages, which err on the side of simplicity.&lt;/li&gt;
&lt;li&gt;Topic variables (&lt;code&gt;@_&lt;/code&gt; and &lt;code&gt;$_&lt;/code&gt;) seem like a bad idea for readability, but really cut down on the tedium of dealing with variable names in cases where it&amp;#39;s obvious. It&amp;#39;s great for short programs, probably not so much for modules.&lt;/li&gt;
&lt;li&gt;Perl&amp;#39;s argument passing reminds me of Javascript, in that you do most of your work explicitly pushing or popping arguments off of your &lt;code&gt;@_&lt;/code&gt; / &lt;code&gt;arguments&lt;/code&gt; stack.&lt;/li&gt;
&lt;li&gt;Perl&amp;#39;s efforts to be backwards-compatible has left it with a lot of vestigial syntax; in a way it suffers from the same problems C++ does in trying to please everyone. The solution for a lot of teams using C++ is to use a well-defined subset of the features, and I believe this parallels making sure to use the latest features of Perl as well.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Tufte and Infographics</title>
   <link href="http://bsumm.net/2010/02/10/tuftian.html"/>
   <updated>2010-02-10T00:00:00-08:00</updated>
   <id>http://bsumm.net/2010/02/10/tuftian</id>
   <content type="html">&lt;p&gt;I&amp;#39;ve recently read Tufte&amp;#39;s &lt;a href=&quot;http://www.amazon.com/Visual-Display-Quantitative-Information/dp/096139210X&quot;&gt;Visual Display of Quantitative Information&lt;/a&gt;.Althought it predates the predominance of digital infographics, the text applies to any two dimensional medium. &lt;/p&gt;

&lt;p&gt;One of the main ideas is that good information design strives to reveal the greatest number of ideas in the shortest time, with the least ink, in the smallest space. &lt;/p&gt;

&lt;p&gt;It&amp;#39;s interesting to contrast this with the trend of infographics, which seek to firstly entertain through visual experiences. Tufte would call this &amp;quot;chartjunk,&amp;quot; as its design does nothing to contribute to a user&amp;#39;s real comprehension of the underlying data. &lt;/p&gt;

&lt;p&gt;I would argue for somewhere in between, that infographics serves a job to be done. It allows those seeking a ready-made conclusion enough facts to support a stance. In other words, it serves as a high schooler&amp;#39;s persuasive essay, emphasizing and summarizing data to aid a predetermined conclusion. In reality, infographics are often presented as supplements to an editorial in another medium, like on cable or in an article, and serve much the same purpose. A Tufte disciple would find the practice of willful filtering of information reprehensible, and would instead seek to create a graphical representation of the &lt;em&gt;entirety&lt;/em&gt; of the data present, with a thought that the display would compel the viewer to her own conclusions. On the whole, I tend to side with information oversharing, as &amp;quot;simplifying&amp;quot; based on presumptions of limited time or critical reasoning skills can often lead to wild misconceptions.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>txting</title>
   <link href="http://bsumm.net/2010/01/08/txting.html"/>
   <updated>2010-01-08T00:00:00-08:00</updated>
   <id>http://bsumm.net/2010/01/08/txting</id>
   <content type="html">&lt;p&gt;There&amp;#39;s something haiku-like about the 160-character limit. The poets of our day will tweet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Happy new year</title>
   <link href="http://bsumm.net/2010/01/01/happy-new-year.html"/>
   <updated>2010-01-01T00:00:00-08:00</updated>
   <id>http://bsumm.net/2010/01/01/happy-new-year</id>
   <content type="html">&lt;p&gt;Happy new year everyone!&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been working on a few projects. One is &lt;a href=&quot;/projects/ijam.html&quot;&gt;iJam&lt;/a&gt;, a 
mobile music app for the iPhone. We hope to have it out sometime in the spring. It 
uses a port of Pure Data, a software synthesizer, called &lt;a href=&quot;/projects/pdlib.html&quot;&gt;pdlib&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Harmony</title>
   <link href="http://bsumm.net/2008/12/04/harmony.html"/>
   <updated>2008-12-04T00:00:00-08:00</updated>
   <id>http://bsumm.net/2008/12/04/harmony</id>
   <content type="html">&lt;p&gt;&amp;quot;Art is harmony.&amp;quot; - Seurat.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
